Explain please why doesnt work .className property? [duplicate] - javascript

This question already has answers here:
Why does jQuery or a DOM method such as getElementById not find the element?
(6 answers)
Closed 5 years ago.
DOM-structure in .html
Theres .js and bootstr containers for making stylish gallery.
<script src="main.js"></script>
<div class="container-fluid" id="gal">
<div class="row">
<div class="col-md-offset-2 col-md-8 col-sm-offset-1 col-sm-10 col-xs-12">
<div class="container-fluid galbody" id="gallery3">
<h2 id="galhead">Gallery</h2>
<div id="col1">
</div>
<div id="col2">
</div>
<div id="col3">
</div>
</div>
<div class="container-fluid galbody" id="gallery2">
<div id="col1">
</div>
<div id="col2">
</div>
</div>
<div class="container-fluid galbody" id="gallery1">
<div id="col1">
</div>
</div>
</div>
</div>
</div>
Im trying to insert within .js functions and methods images that are in array arr[] urls.
there is an main.js code:
document.write("hey!");
//definin' width of browser workspace
var galdiv3 = document.getElementById("gallery3").className = "none";
var galdiv2 = document.getElementById("gallery2").className = "none";
var galdiv1 = document.getElementById("gallery1").className = "none";
//creating array of future gallerydir images paths list
var arr = [];
//creating async flow for read json with paths. after calling back func for parse read text as array list in array (arr)
fs.readFile("gallist.json", function cb(err,rd){
var imgList = JSON.parse(rd);
imgList.forEach(function(file) {
arr += file + ", ";
}, this);
console.log(arr);
});
function singleGrid()
{
galdiv1.removeAttribute(className = " none");
function imgFill(){
for (var file in arr){
var x = document.createElement("div");
x.className();
}
}
imgFill();
}
singleGrid();
Problem is there :
var galdiv3 = document.getElementById("gallery3")**.className = "none"**;
var galdiv2 = document.getElementById("gallery2")**.className = "none"**;
var galdiv1 = document.getElementById("gallery1")**.className = "none"**;
Console throws err "Uncaught TypeError: Cannot set property 'className' of null"

you're trying to access DOM element before they've been inserted into the page.
so in the expression
var galdiv3 = document.getElementById("gallery3").className = "none";
the expression document.getElementById("gallery3") returns null. as consequence: null.className throws the error.
this happens because the <script></script> tag executes his content in the moment it's added to the page, that is, during the loading of the page, before the other tags are added. For this, when the script is executed, there are no other elements in the page so that you cannot find them.
move the <script src="main.js"></script> to the bottom or simply put all the code inside the window.onload event.

Related

After adding querySelector inside function page crash

With this function, every div element that has children needs to wrap the children in a wrap div. Everything works fine if
<button id="run" onclick="wrapChildren(document.querySelector('#element1'))">Run</button>
but at the moment when I insert in the function:
var element = document.querySelector('#element1');
the page is crashing "devtools was disconnected from the page". Why is this happening and how to fix?
function wrapChildren() {
var element = document.querySelector('#element1');
const childElements = Array.from(element.children);
if (childElements.length === 0) {
return;
}
const wrapDiv = document.createElement('div');
wrapDiv.id = element.id+"wrap";
childElements.forEach((childElement) => {
wrapDiv.appendChild(childElement);
});
element.appendChild(wrapDiv);
childElements.forEach((childElement) => {
wrapChildren(childElement);
});
}
<div id="element1">
<div id="child1">
<div id="grandchild1"></div>
<div id="grandchild2">
<div id="granddrandchild1"></div>
<div id="granddrandchild2"></div>
<div id="granddrandchild3">
<div id="granddrandgrandchild1"></div>
</div>
</div>
</div>
<div id="child2"></div>
</div>
<button id="run" onclick="wrapChildren()">Run</button>
The way you have written it, your wrapChildren function doesn't actually take any arguments:
function wrapChildren()
so it was always running exactly the same code, even when you attempt to call it recursively with a different argument (in the forEach at the end of your function). As a result, your code leads to infinite recursion and hence a page crash.
To fix this, just give it an element as the argument, and use this element in the function body rather than hardcoding element to be the one with id element1.
I have made this change below and there is no crash any more. The function doesn't actually appear to do anything very much, but I'll leave that to you to sort out, or perhaps ask a new question about. (I don't actually know what this is trying to do.)
function wrapChildren(element) {
const childElements = Array.from(element.children);
if (childElements.length === 0) {
return;
}
const wrapDiv = document.createElement('div');
wrapDiv.id = element.id+"wrap";
childElements.forEach((childElement) => {
wrapDiv.appendChild(childElement);
});
element.appendChild(wrapDiv);
childElements.forEach((childElement) => {
wrapChildren(childElement);
});
}
<div id="element1">
<div id="child1">
<div id="grandchild1"></div>
<div id="grandchild2">
<div id="granddrandchild1"></div>
<div id="granddrandchild2"></div>
<div id="granddrandchild3">
<div id="granddrandgrandchild1"></div>
</div>
</div>
</div>
<div id="child2"></div>
</div>
<button id="run" onclick="wrapChildren(document.querySelector('#element1'))">Run</button>

When clicking on one of the tags with the same class as javascript, how to access the clicked one? [duplicate]

This question already has answers here:
How to get the element clicked (for the whole document)?
(10 answers)
Closed 12 months ago.
When clicking on one of the tags with the same class as javascript, how to access the clicked one? I tried by clicking, I looked at the problems, but unfortunately I could not solve the problem, it is very important for me, thanks in advance. Kind regards
HTML:
<div class="money-select">
<div class="money-check">
<div class="money-check-left">
<img src="https://cdn.dsmcdn.com/ty100/product/media/images/20210408/17/78753423/161972772/0/0_org_zoom.jpg">
<h2>BTC</h2>
</div>
<div class="money-check-right">
<i class="fi-xwsdxl-chevron-wide"></i>
</div>
</div>
<div class="dropdown">
<div class="money-check">
<div class="money-check-left">
<img src="https://cdn.iconscout.com/icon/free/png-256/ethereum-2296075-1912034.png">
<h2>ETH</h2>
</div>
</div>
<div class="money-check">
<div class="money-check-left">
<img src="https://cryptologos.cc/logos/thumbs/bnb.png?v=022">
<h2>BNB</h2>
</div>
</div>
<div class="money-check">
<div class="money-check-left">
<img src="https://cryptologos.cc/logos/thumbs/shiba-inu.png?v=022">
<h2>SHIBA</h2>
</div>
</div>
<div class="money-check">
<div class="money-check-left">
<img src="https://cryptologos.cc/logos/thumbs/decentraland.png?v=022">
<h2>DTC</h2>
</div>
</div>
</div>
</div>
JS:
let moneySelect = document.querySelector(".money-select");
let moneyList = moneySelect.querySelector(".money-check");
let moneyValue = moneyList.querySelector("h1");
let input = document.getElementById("htmlinamk");
for (var i = 0; i < moneyList.length; i++) {
moneyList[i].addEventListener("click", function () {
a = moneyValue.innerText;
input.value = a;
});
}
Sorry for my bad english
The event listener function receives the event object, which has a target property that would point to the div element with class money-check. You could then traverse the DOM tree and get down to child of child and extract the inner text from the header tag. Something like this:
moneyList[i].addEventListener("click", (event) => {
const innerText = event.target.child<traverse here>.innerText;
input.value = innerText;
});
There are 2 ways to get the element that was clicked. this, or event.target. Either of the techniques will work for this example:
moneyList[i].addEventListener("click", function (e) {
let a = this.querySelector('H2').innerText;
// let a = e.target.querySelector('H2').innerText;
input.value = a;
});

ShuffleJS cannot read property 'textContent' of null

I'm learning ShuffleJS to use it in a project, but I'm running into problems with the search functionality. When I'm trying to search for my items, I keep getting this error:
Cannot read property 'textContent' of null
I grabbed the search code from the docs, but it doesn't seem to work for me.
Here's some code of my search functionality:
HTML
<section class="search">
<div class="container">
<div class="row">
<div class="col-12">
<div class="form-group">
<input type="search" id="search" class="form-control">
</div>
</div>
</div>
</div>
</section>
<section>
<div class="container">
<div class="row" id="grid">
<div class="box green" data-groups='["green"]' data-title="blue">green</div>
<div class="box red" data-groups='["red"]' data-title="red">red</div>
<div class="box green" data-groups='["green"]' data-title="blue">green</div>
<div class="box red" data-groups='["red"]' data-title="red">red</div>
<div class="box green" data-groups='["green"]' data-title="blue">green</div>
<div class="box red" data-groups='["red"]' data-title="red">red</div>
<div class="col-md-2 my-sizer"></div>
</div>
</div>
</section>
JS
const Shuffle = window.Shuffle;
const element = $('#grid');
const sizer = $('.my-sizer');
const shuffle = new Shuffle(element, {
itemSelector: '.box',
sizer
})
$('#search').on('keyup', (e) => {
var searchText = e.target.value.toLowerCase();
shuffle.filter((element, shuffle) => {
var titleElement = element.querySelector('.box');
var titleText = titleElement.textContent.toLowerCase().trim(); // <= this is where the error is thrown
return titleText.indexOf(searchText) !== -1;
});
})
I've also attempted to copy and paste their example JS file here, but I get the same error mentioned above.
I've also reproduced the code written above in a CodePen!
Would anyone know where the problem is? Thanks for the help!
In your filter function, it seems element is already a div with the class box. So there's no need to look within element for an element with class box, as you've already got it.
So you can replace
var titleElement = element.querySelector('.box');
var titleText = titleElement.textContent.toLowerCase().trim(); // <= this is where the error is thrown
with
var titleText = element.textContent.toLowerCase().trim();

Is there a way to change a card text using JavaScript? [duplicate]

This question already has answers here:
Why does jQuery or a DOM method such as getElementById not find the element?
(6 answers)
Closed 2 years ago.
I am trying to change the text from "yes" to "ok," but get the error: Uncaught TypeError: Cannot read property 'addEventListener' of null.
JS
// create DOM element references
let card1= document.querySelector("div.class-1");
card1.addEventListener("mouseenter", function() {
let text1 = document.querySelector("p.card-text");
console.log(text1);
text1.innerHTML = "Ok";
});
HTML
<div class="col-sm-12 col-md-6 col-lg-4 pb-4">
<div class="card-item card-1">
<p class="card-text">Yes</p>
</div>
</div>
There is no div tag that has .class-1 class. From your html code, you need to find the selector with div.card-1 as follows.
let card1 = document.querySelector("div.card-1");
card1.addEventListener("mouseenter", function () {
let text1 = document.querySelector("p.card-text");
console.log(text1);
text1.innerHTML = "Ok";
});
<div class="col-sm-12 col-md-6 col-lg-4 pb-4">
<div class="card-item card-1">
<p class="card-text">Yes</p>
</div>
</div>

array_chunk in Javascript, after Appending a big chunk using ForLoop

(In edit part at the bottom, I have included my code that I got closest)
Explanation:
I have an ajax post, which fetches data from controller. On success, I have a for loop for each post:
success: function(data) {
var posts = data['data'];
var postsCount = data['per_page'];
var frag = document.createDocumentFragment();
for(i=0; i < postsCount; i++){
frag.appendChild(postElem(posts));
}
document.getElementById('content').appendChild(frag);
}
I also have another function function postElement() which creates eachPost div, appends the child divs into eachPost and returns it
function postElem(posts){
var eachPost = document.createElement('div');
eachPost.className = "col-md-4 eachPost";
//and a big chunk of code that finally appends into `eachPost`.
return eachPost;
}
This works perfectly until here
The structure I got working in html, and also want to achieve in javascript looks like this:
<div id="content">
#foreach (array_chunk($posts->all(), 3) as $row)
<div class="row eachRow">
#foreach($row as $post)
<div class="col-md-3 eachPost">
<!-- rest of the code -->
After some research, I figured out I can achieve array_chunk like this:
var n,j,tempArray,chunk = 3;
for (n=0,j=posts.length; n<j; n+=chunk) {
tempArray = posts.slice(n,n+chunk);
// my other `for`.
}
However, whatever I tried, I couldn't figure out how I can achieve what I achieved in html. I couldn't import eachRow bit in javascript. What is the way of doing it? Is it because of the document.createDocumentFragment() bit?
Edit: What I tried, that fails what I want to achieve:
success: function(data) {
var posts = data['data'];
var postsCount = data['per_page'];
var frag = document.createDocumentFragment();
var eachRow = document.createDocumentFragment();
var n,j,tempArray,chunk = 3;
for (n=0,j=posts.length; n<j; n+=chunk) {
tempArray = posts.slice(n,n+chunk);
for(i=0; i < tempArray.length; i++){
frag.appendChild(postElem(tempArray));
}
var eachRow = document.createElement('div');
eachRow.className = "row eachRow";
eachRow.appendChild(frag);
}
document.getElementById('content').appendChild(eachRow);
}
In this part, it appends the stuff in frag. It creates a div. (See bottom for the view:source)
This creates a post inside each row, and it's like a straight line of posts, instead of 3 posts in 1 row.
What I want to achieve
<div class="row eachRow">
<div class="eachPost>_</div>
<div class="eachPost>_</div>
<div class="eachPost>_</div>
</div>
<div class="row eachRow">
<div class="eachPost>_</div>
<div class="eachPost>_</div>
<div class="eachPost>_</div>
</div>
The code at the top is producing:
<div class="row eachRow">_</div>
<div class="row eachRow">_</div>
<!-- for each bit -->
<div class="eachPost>_</div>
<div class="eachPost>_</div>
<div class="eachPost>_</div>
Code in edit part is producing:
<div class="row eachRow">
<div class="eachPost>_</div>
</div>
<div class="row eachRow">
<div class="eachPost>_</div>
</div>
<div class="row eachRow">
<div class="eachPost>_</div>
</div>

Categories

Resources