The html I'm looking at looks like this:
document.querySelectorAll('h4#unique_id ~ h5 ~p +p +h5').forEach(title => console.log(title))
<body>
<h4 id="unique_id"> foo bing bar </h4>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<!-- selection should start here -->
<h5>title text 1</h5>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<h5>title text 2</h5>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<h5>title text 3</h5>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<!-- and end here -->
<h4 id="randome_id_234353">title text</h4>
<p>some text I don't want</p>
<p>some text I don't want</p>
<h5>title text I don't want</h5>
<p>some text I don't want</p>
<h5>title text I don't want</h5>
<p>some text I don't want</p>
<h5>title text I don't want</h5>
<p>some text I don't want</p>
</body>
I want to grab all the h5 elements, and if possible the p elements as well.
I have document.querySelectorAll('h4#unique_id ~ h5 ~p +p +h5') so far but that misses the first h5 I want and grabs the last one I don't want. I can't figure out sibling selectors or how to use :not or similar to stop when I find another h4.
This question Select all elements between two known elements by CSS selector relies on jquery which I don't have access to, and Select elements between two defined elements relies on knowning the number and position of elements, which I don't.
Is this possible with just css selectors?
Ok you can use a mixture of sibling selector and not:
The selector is:
#unique_id~p:not(#unique_id~h4~p) /* any p following the unique id but not a p following another h4 after the unique id */
you then repeat this selector for your h5s and the result is:
document.querySelectorAll('#unique_id~p:not(#unique_id~h4~p),#unique_id~h5:not(#unique_id~h4~h5)').forEach(title => title.style.color = 'red');
<h4 id="unique_id"> foo bing bar </h4>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<h5>title text 1</h5>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<h5>title text 2</h5>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<h5>title text 3</h5>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<h4 id="randome_id_234353">title text</h4>
<p>some text I don't want</p>
<p>some text I don't want</p>
<h5>title text I don't want</h5>
<p>some text I don't want</p>
<h5>title text I don't want</h5>
<p>some text I don't want</p>
<h5>title text I don't want</h5>
<p>some text I don't want</p>
As per your edit - not to include the p before the first h5 (selector is slightly modified from Alohci's comment):
document.querySelectorAll('#unique_id~:is(h5, h5~p):not(#unique_id ~ h4 ~ *)').forEach(title => title.style.color = 'red');
<h4 id="unique_id"> foo bing bar </h4>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<h5>title text 1</h5>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<h5>title text 2</h5>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<h5>title text 3</h5>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<h4 id="randome_id_234353">title text</h4>
<p>some text I don't want</p>
<p>some text I don't want</p>
<h5>title text I don't want</h5>
<p>some text I don't want</p>
<h5>title text I don't want</h5>
<p>some text I don't want</p>
<h5>title text I don't want</h5>
<p>some text I don't want</p>
Interesting question. If I understand your problem correctly, you want to log all of the elements that are not containing some text I don't want and the h5-elements.
If you have a parent element, you can use the > to selector in combination with the parent element to select all of its children with the *-selector.
You can apply multiple :not()-selectors to a statement. Below I just selected all p and h4-elements that are preceded by the h4#randome_id_234353-element, like so:
document.querySelectorAll('.container > *:not(h4#randome_id_234353 ~ p):not(h4#randome_id_234353 ~ h5):not(h4)').forEach(title => console.log(title))
<body>
<div class="container">
<h4 id="unique_id"> foo bing bar </h4>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<h5>title text 1</h5>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<h5>title text 2</h5>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<h5>title text 3</h5>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<h4 id="randome_id_234353">title text</h4>
<p>some text I don't want</p>
<p>some text I don't want</p>
<h5>title text I don't want</h5>
<p>some text I don't want</p>
<h5>title text I don't want</h5>
<p>some text I don't want</p>
<h5>title text I don't want</h5>
<p>some text I don't want</p>
</div>
</body>
If you don't have a container, you can use the same logic to log everything that does not preceed h4#randome_id_234353.
document.querySelectorAll('h4#unique_id ~ *:not(h4#randome_id_234353 ~ *):not(h4#randome_id_234353)').forEach(title => console.log(title))
<body>
<h4 id="unique_id"> foo bing bar </h4>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<h5>title text 1</h5>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<h5>title text 2</h5>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<h5>title text 3</h5>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<h4 id="randome_id_234353">title text</h4>
<p>some text I don't want</p>
<p>some text I don't want</p>
<h5>title text I don't want</h5>
<p>some text I don't want</p>
<h5>title text I don't want</h5>
<p>some text I don't want</p>
<h5>title text I don't want</h5>
<p>some text I don't want</p>
</body>
Only a small number of array methods work with array-like objects, so I often find it useful to turn a NodeList (which is an iterable, array-like object but, crucially, not an array) into an array, so that I can do many more things with it.
In this case by turning NodeList into an array I can use the javascript method .filter() which is exactly what I need to remove the unwanted elements from the end of the collection.
Turning a NodeList into an array:
How can I turn this static NodeList:
let myClassElements = document.querySelectorAll('.myclass');
into an array?
By combining spread syntax (...) with an array literal ([]):
let myClassElements = [... document.querySelectorAll('.myclass')];
On that basis, I can create an array of all the elements I do need (plus a few unnecessary ones):
[...document.querySelectorAll('h4#unique_id ~ h5, h4#unique_id ~ p')]
and also another array of all the unnecessary elements:
[...document.querySelectorAll('h4:not(#unique_id) ~ h5, h4:not(#unique_id) ~ p')]
And then I can .filter() out the latter from the former:
const rawListOfElements = [...document.querySelectorAll('h4#unique_id ~ h5, h4#unique_id ~ p')];
const elementsToRemove = [...document.querySelectorAll('h4:not(#unique_id) ~ h5, h4:not(#unique_id) ~ p')];
const mySelectedElements = rawListOfElements.filter((element) => elementsToRemove.includes(element) === false).forEach(title => console.log(title));
Working Example:
const rawListOfElements = [...document.querySelectorAll('h4#unique_id ~ h5, h4#unique_id ~ p')];
const elementsToRemove = [...document.querySelectorAll('h4:not(#unique_id) ~ h5, h4:not(#unique_id) ~ p')];
const mySelectedElements = rawListOfElements.filter((element) => elementsToRemove.includes(element) === false).forEach(title => console.log(title));
<body>
<h4 id="unique_id"> foo bing bar </h4>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<!-- selection should start here -->
<h5>title text 1</h5>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<h5>title text 2</h5>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<h5>title text 3</h5>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<!-- and end here -->
<h4 id="randome_id_234353">title text</h4>
<p>some text I don't want</p>
<p>some text I don't want</p>
<h5>title text I don't want</h5>
<p>some text I don't want</p>
<h5>title text I don't want</h5>
<p>some text I don't want</p>
<h5>title text I don't want</h5>
<p>some text I don't want</p>
</body>
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
body {
overflow: hidden;
}
.wrapper {
overflow-y: auto;
overflow-x: hidden;
display: flex;
height: 30vh;
margin: 24px;
background: rgb(194,194,194);
}
.sidebar {
flex: 0 0 150px;
padding: 12px;
background: rgb(245, 134, 134);
}
.content {
flex: 1 1 auto;
width: calc(100% - 150px);
padding: 12px;
background: rgb(11, 134, 134);
}
.content-inner {
display: flex;
}
.content-inner > p {
flex: 0 0 80px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>A Great Demo on CodePen</title>
</head>
<body>
<div class="wrapper">
<div class="sidebar">
<header>Sidebar</header>
<div class="sidebar-content">
<p>Sidebar content</p>
<p>Sidebar content</p>
<p>Sidebar content</p>
<p>Sidebar content</p>
<p>Sidebar content</p>
<p>Sidebar content</p>
<p>Sidebar content</p>
<p>Sidebar content</p>
<p>Sidebar content</p>
<p>Sidebar content</p>
<p>Sidebar content</p>
<p>Sidebar content</p>
<p>Sidebar content</p>
<p>Sidebar content</p>
<p>Sidebar content</p>
<p>Sidebar content</p>
</div>
</div>
<div class="content">
<div class="content-inner">
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
</div>
<div class="content-inner">
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
</div>
<div class="content-inner">
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
</div>
<div class="content-inner">
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
</div>
<div class="content-inner">
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
</div>
<div class="content-inner">
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
</div>
<div class="content-inner">
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
</div>
<div class="content-inner">
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
</div>
<div class="content-inner">
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
</div>
<div class="content-inner">
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
</div>
<div class="content-inner">
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
</div>
<div class="content-inner">
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
</div>
</div>
</div>
</body>
</html>
I have a weird situation, but I hope, it is actual, in general.
As you could notice, the whole wrapper scrolls vertically.
The expected behavior is that I want the content section to be scrolled horizontally without affecting sidebar (means that sidebar should be always visible and static while scrolling horizontally) and at the same time, the whole content should scrollable vertically as it is now.
I can only achieve the first case, but in that case, when the whole content is being scrolled vertically, content sections vertical scrollbar causes it's content to be cut vertically.
Note that the horizontal scrollbar should be visible on the viewport, and not be at the bottom of the whole content, as the content can be much longer
I want to achieve this via CSS. I can do this with JavaScript I assume, but better to be done by CSS.
I made these two changes to make it work -
Adding align-items: flex-start to .wrapper, this solves the issue of containers getting cut.
Adding overflow-x: auto to .content, to enable horizontal scrolling.
body {
overflow: hidden;
}
.wrapper {
overflow-y: auto;
overflow-x: hidden;
display: flex;
height: 40vh;
margin: 24px;
background: rgb(194,194,194);
align-items: flex-start;
}
.sidebar {
flex: 0 0 150px;
padding: 12px;
background: rgb(245, 134, 134);
}
.content {
overflow-x: auto;
flex: 1 1 auto;
width: calc(100% - 150px);
padding: 12px;
background: rgb(11, 134, 134);
}
.content-inner {
display: flex;
}
.content-inner > p {
flex: 0 0 80px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>A Great Demo on CodePen</title>
</head>
<body>
<div class="wrapper">
<div class="sidebar">
<header>Sidebar</header>
<div class="sidebar-content">
<p>Sidebar content</p>
<p>Sidebar content</p>
<p>Sidebar content</p>
<p>Sidebar content</p>
<p>Sidebar content</p>
<p>Sidebar content</p>
<p>Sidebar content</p>
<p>Sidebar content</p>
<p>Sidebar content</p>
<p>Sidebar content</p>
<p>Sidebar content</p>
<p>Sidebar content</p>
<p>Sidebar content</p>
<p>Sidebar content</p>
<p>Sidebar content</p>
<p>Sidebar content</p>
<p>Sidebar content</p>
</div>
</div>
<div class="content">
<div class="content-inner">
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
</div>
<div class="content-inner">
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
</div>
<div class="content-inner">
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
</div>
<div class="content-inner">
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
</div>
<div class="content-inner">
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
</div>
<div class="content-inner">
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
</div>
<div class="content-inner">
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
</div>
<div class="content-inner">
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
</div>
<div class="content-inner">
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
</div>
<div class="content-inner">
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
</div>
<div class="content-inner">
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
</div>
<div class="content-inner">
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
</div>
</div>
</div>
</body>
</html>
This works for me.
.scroll-area {
width:85%;
float:left;
overflow: scroll;
white-space:nowrap;
}
ul li {
display: inline;
}
.sidebar
{
width:15%;
float:left;
}
<div class="sidebar">
<h1 class="logo">Title</h1>
</div>
<div class="rightcontent">
<div class="scroll-area">
<div class="image-gallery">
<ul>
<li><img src="http://placehold.it/500x800"></li>
<li><img src="http://placehold.it/500x800"></li>
<li><img src="http://placehold.it/500x800"></li>
</ul>
</div>
</div>
</div>
All I'm attempting to do right now is get the scroll position, and it isn't working for some reason.
jQuery(document).ready(function() {
$("#showScroll").html("Scroll = " + "Testing Text");
jQuery(window).scroll(function() {
$("#showScroll").html("Scroll = " + $(this).scroll() + " : " + $(this).scrollTop());
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<p>random Text</p>
<p>random Text</p>
<p>random Text</p>
<p>random Text</p>
<p>random Text</p>
<p>random Text</p>
<p>random Text</p>
<p>random Text</p>
<p>random Text</p>
<p>random Text</p>
<p>random Text</p>
<p>random Text</p>
<div>
<p id="showScroll">Scroll is: </p>
</div>
<p>random Text</p>
<p>random Text</p>
<p>random Text</p>
<p>random Text</p>
<p>random Text</p>
<p>random Text</p>
<p>random Text</p>
</div>
I have also tried placing the scroll listener on document, this, and divs to no avail.
Remove $(this).scroll(). You only need .scrollTop() to retrieve the scroll offset.
jQuery(document).ready(function() {
$("#showScroll").html("Scroll = " + "Testing Text");
jQuery(window).scroll(function() {
$("#showScroll").html("Scroll = " + $(this).scrollTop());
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<p>random Text</p>
<p>random Text</p>
<p>random Text</p>
<p>random Text</p>
<p>random Text</p>
<p>random Text</p>
<p>random Text</p>
<p>random Text</p>
<p>random Text</p>
<p>random Text</p>
<p>random Text</p>
<p>random Text</p>
<div>
<p id="showScroll">Scroll is: </p>
</div>
<p>random Text</p>
<p>random Text</p>
<p>random Text</p>
<p>random Text</p>
<p>random Text</p>
<p>random Text</p>
<p>random Text</p>
</div>
I have an active sidebar navigation, which is not moving up with all the website content when you scroll down the page.
My problem is, that it is working the way I want it to work on a desktop browser, but it jumps up and down and doesn't allow any scrolling as soon as I decrease the browser size or run it as a mobile preview (Chrome Developer Tools)
Here is a: jsfiddle, which unfortunately doesn't work. But the code below works fine! You can just copy it into an html file.
<!DOCTYPE html>
<html>
<head>
<!-- jQuery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<!-- Bootstrap -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>
<!-- Side Navbar -->
<div class="container">
<div class="row">
<!--left-->
<div class="col-md-3" id="leftCol">
<ul class="nav nav-stacked" id="sidebar">
<li>
<div id="sideBarLogo">
<a href="#">
<img class="img-responsive" style="display:inline-block; height:120px; margin-top:200px" src="images/logo.png" alt="Logo">
<br><br><br><br>
</a>
</div>
</li>
<li><p class="raleway">Menu 1</p></li>
<li><p class="raleway">Menu 2</p></li>
<li><p class="raleway">Menu 3</p></li>
<li><p class="raleway">Menu 4</p></li>
<li><p class="raleway">Menu 5</p></li>
</ul>
</div>
<!--/left-->
<!--right-->
<div class="col-md-9">
<p>text text text</p>
<p>text text text</p>
<p>text text text</p>
<p>text text text</p>
<p>text text text</p>
<br><br><br><br><br>
<p>text text text</p>
<p>text text text</p>
<p>text text text</p>
<p>text text text</p>
<p>text text text</p>
<br><br><br><br><br>
<p>text text text</p>
<p>text text text</p>
<p>text text text</p>
<p>text text text</p>
<p>text text text</p>
<br><br><br><br><br>
<p>text text text</p>
<p>text text text</p>
<p>text text text</p>
<p>text text text</p>
<p>text text text</p>
<br><br><br><br><br>
<p>text text text</p>
<p>text text text</p>
<p>text text text</p>
<p>text text text</p>
<p>text text text</p>
<br><br><br><br><br>
<p>text text text</p>
<p>text text text</p>
<p>text text text</p>
<p>text text text</p>
<p>text text text</p>
<br><br><br><br><br>
<p>text text text</p>
<p>text text text</p>
<p>text text text</p>
<p>text text text</p>
<p>text text text</p>
<br><br><br><br><br>
</div>
</div>
</div>
</body>
</html>
<script>
/* activate sidebar */
$('#sidebar').affix({
offset: {
top: 235
}
});
</script>
If somebody knows a solution, I appreciate it alot. Many thank in advance!
Here is what the code looks like:
<div class='class1'>
<div class='class2'>
<div class='class3'>
<div class='class4'>
<div class='class5'>
<p>Some text 1</p>
</div>
</div>
<div class='class4'>
<div class='class5'>
<p>Some text 1</p>
</div>
</div>
<div class='class4'>
<div class='class5' style="display:block;">
<p>Some text 1</p>
</div>
</div>
<div class='class4'>
<div class='class5'>
<p>Some text 1</p>
</div>
</div>
</div>
</div>
</div>
I want to get the div with class5 and CSS property display set to block. Once I have this div I want to perform further action on that div. I tried using something like
$('.class1 .class2 .class3 .class4').find( '.class5').is(':visible')
but it doesn't work.
The problem you have is that is() returns a Boolean, reflecting whether the passed-in element (or the first of the passed-in elements) matches the supplied argument.
If you switch to filter(), which filters the passed-in collection according to the supplied argument; if the element matches then that element is retained, otherwise it's discarded:
let classFiveElems = $('.class1 .class2 .class3 .class4 .class5').filter( ':visible');
console.log(classFiveElems);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='class1'>
<div class='class2'>
<div class='class3'>
<div class='class4'>
<div class='class5'>
<p>Some text 1</p>
</div>
</div>
<div class='class4'>
<div class='class5'>
<p>Some text 1</p>
</div>
</div>
<div class='class4'>
<div class='class5' style="display:block;">
<p>Some text 1</p>
</div>
</div>
<div class='class4'>
<div class='class5'>
<p>Some text 1</p>
</div>
</div>
</div>
</div>
</div>
What you want, though, is not just a simple check for visibility; but a test for a specific CSS property; so I'd suggest the following, which uses filter() but using the anonymous function:
let classFiveElems = $('.class1 .class2 .class3 .class4 .class5').filter(function() {
return this.style.display === 'block';
}).addClass('found');
console.log(classFiveElems);
.found {
color: #f90;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='class1'>
<div class='class2'>
<div class='class3'>
<div class='class4'>
<div class='class5'>
<p>Some text 1</p>
</div>
</div>
<div class='class4'>
<div class='class5'>
<p>Some text 1</p>
</div>
</div>
<div class='class4'>
<div class='class5' style="display:block;">
<p>Some text 1</p>
</div>
</div>
<div class='class4'>
<div class='class5'>
<p>Some text 1</p>
</div>
</div>
</div>
</div>
</div>
References:
filter().
find().
is().
As example:
if($('.class1 .class2 .class3 .class4')
.find( '.class5:first')
.is(':visible')){
console.log('yes');
}
See: https://jsbin.com/ninovic/edit?html,js,console,output
.is() returns a boolean, you can use the pseudo-selector inside find() to select the element:
$('.class1 .class2 .class3 .class4').find('.class5:visible')
Example
$('.class5').each(function(){
if ($(this).is(":visible")) {
//What you want to do
}
});
You can do it directly
alert('is visible?', $( '.class5').is(':visible'));
Actually every div with class5 class has a display: block property.
display: block property is a default state of every block element (divs are block elements).
I've set the display property of other divs to none, just to show functionality of following code.
$('div').each(function() {
if ($(this).hasClass('class5') && $(this).is(":visible")) {
console.log($(this).html());
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='class1'>
<div class='class2'>
<div class='class3'>
<div class='class4'>
<div class='class5' style="display:none;">
<p>Some text 1</p>
</div>
</div>
<div class='class4'>
<div class='class5' style="display:none;">
<p>Some text 2</p>
</div>
</div>
<div class='class4'>
<div class='class5' value='t' style="display:block;">
<p>Some text 3</p>
</div>
</div>
<div class='class4'>
<div class='class5' style="display:none;">
<p>Some text 4</p>
</div>
</div>
</div>
</div>
</div>
This will return the .class5 having display:block property. IN Your case it will return all the elements. because all div in div contains default display property block, So it will return all of them in your case. and if you try then you have assure that only the elements(.class5) you want to select have display block property.
var selector = $('.class1 .class2 .class3 .class4').find( '.class5').filter(function() {
return $(this).css('display') == 'block';
});
I am looking to use jQuery to select the p tags which are the grandparent element of a span with a certain class hdr, I then want to wrap that p tag and all of it's siblings up until the next p tag which is a parent of a hdr class, so on and so forth.
The problem I have is that the 2nd and 3rd wrappers and it's containing content end up getting nested inside of their previous set of wrappers instead of each wrapper being printed one after another.
My Initial Markup:
$('.main .hdr').parents('p').each(function() {
$(this).nextUntil($(this)).addBack().wrapAll('<div class="wrapper" />');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="main">
<p><strong><span class="hdr">Heading #1</span></strong></p>
<p>Some paragraph text</p>
<p>Some paragraph text</p>
<p>Some paragraph text</p>
<p>Some paragraph text</p>
<p><strong><span class="hdr">Heading #2</span></strong></p>
<p>Some paragraph text</p>
<p>Some paragraph text</p>
<p><strong><span class="hdr">Heading #3</span></strong></p>
<p>Some paragraph text</p>
<p>Some paragraph text</p>
<p>Some paragraph text</p>
<p>Some paragraph text</p>
<p>Some paragraph text</p>
</div>
Current Output:
<div class="main">
<div class="wrapper">
<p><strong><span class="hdr">Heading #1</span></strong></p>
<p>Some paragraph text</p>
<p>Some paragraph text</p>
<p>Some paragraph text</p>
<p>Some paragraph text</p>
<div class="wrapper">
<p><strong><span class="hdr">Heading #2</span></strong></p>
<p>Some paragraph text</p>
<p>Some paragraph text</p>
<div class="wrapper">
<p><strong><span class="hdr">Heading #3</span></strong></p>
<p>Some paragraph text</p>
<p>Some paragraph text</p>
<p>Some paragraph text</p>
<p>Some paragraph text</p>
<p>Some paragraph text</p>
</div>
</div>
</div>
</div>
Desired Output:
<div class="main">
<div class="wrapper">
<p><strong><span class="hdr">Heading #1</span></strong></p>
<p>Some paragraph text</p>
<p>Some paragraph text</p>
<p>Some paragraph text</p>
<p>Some paragraph text</p>
</div>
<div class="wrapper">
<p><strong><span class="hdr">Heading #2</span></strong></p>
<p>Some paragraph text</p>
<p>Some paragraph text</p>
</div>
<div class="wrapper">
<p><strong><span class="hdr">Heading #3</span></strong></p>
<p>Some paragraph text</p>
<p>Some paragraph text</p>
<p>Some paragraph text</p>
<p>Some paragraph text</p>
<p>Some paragraph text</p>
</div>
</div>
JSFiddle
Something like this, passing in the selection to nextUntil, or even just p:has(.hdr) would work, instead of $(this)
var elems = $('.main p:has(.hdr)');
elems.each(function() {
$(this).nextUntil(elems).addBack().wrapAll('<div class="wrapper" />');
});
FIDDLE