How to get on-screen visible element objects in jQuery? [duplicate] - javascript

This question already has answers here:
How can I tell if a DOM element is visible in the current viewport?
(31 answers)
Closed 9 years ago.
I have a list of objects in DOM, which is longer than screen height area.
I need to detect on-screen visible objects only to make something like timeline tree-view. (something like on the picture below):
My DOM looks like this:
<!-- elements visibility on screen to be DETECTED -->
<div id="elements">
<div id="elem-1">Lorem ipsum</div>
<div id="elem-2">Lorem ipsum</div>
<div id="elem-3">Lorem ipsum</div>
<div id="elem-4">Lorem ipsum</div>
<div id="elem-5">Lorem ipsum</div>
<div id="elem-6">Lorem ipsum</div>
<div id="elem-7">Lorem ipsum</div>
<div id="elem-8">Lorem ipsum</div>
</div>
<!--elements visibility on screen to be AFFECTED -->
<ul id="timeline">
<li view-id="elem-1">Elem-1</li>
<li view-id="elem-2">Elem-2</li>
<li view-id="elem-3" class="active">Elem-3</li>
<li view-id="elem-4" class="active">Elem-4</li>
<li view-id="elem-5" class="active">Elem-5</li>
<li view-id="elem-6" class="active">Elem-6</li>
<li view-id="elem-7">Elem-7</li>
<li view-id="elem-8">Elem-8</li>
</ul>
My goal is to detect IDs' of on-screen visible elements from #elements container and assign active class to corresponding elements in #timeline container.
I need to do this process on Scroll event.
Any ideas how to achieve this?

First of all on-screen visible area is known as Viewport.
(image is taken from OP. Cleared and edited in Photoshop)
So all you need is to detect all elements in your Viewport.
This can be achieved using many plugins for jQuery, but I'll explain you on one example, which is called as jQuery withinviewport
Link to source and documentation on: [ withInViewport - Github ]
Step 1:
Download plugins and include jQuery framework and withinviewport plugin in your script:
<script src="http://code.jquery.com/jquery-1.7.min.js"></script>
<script src="withinViewport.js"></script>
<script src="jquery.withinviewport.js"></script>
.
Step 2:
Initialise function on scroll event:
$(window).bind("scroll", function() {
//your code placeholder
});
.
Step 3:
Use withinviewport selector to get all elements in you Viewport and by each element add class to corresponding list-item in your #timeline container:
$("#elements > div").withinviewport().each(function() {
$('#timeline > li[view-id="'+$(this)[0].id+'"]').addClass('active');
});
Step 4:
Put all together:
$(window).bind("scroll", function() {
//clear all active class
$('#timeline > li').removeClass('active');
//add active class to timeline
$("#elements > div").withinviewport().each(function() {
$('#timeline > li[view-id="'+$(this)[0].id+'"]').addClass('active');
});
});
.
.
Also this plugin gives you opportunity to set top, bottom, left and right offset for view-port.
See demo here: http://patik.com/code/within-viewport/

Related

When hovering over an element with a certain index, change the styles of the element in another parent with the same index

I have a menu on the site in two places. One is made by text, and the other by pictures. You can click on both.
I want that when you hover over a specific item in a text menu (for example, under number 2), the picture with the same number changes (for example, under 2).
Code for text menu:
<ul>
<li class="page_item">
Test 1
</li>
<li class="page_item">
Test 2
</li>
</ul>
Code for Pictures menu:
<div class="project__card project__card-design">
<div class="project__card-design-bigelem">
</div>
<div class="project__card-design-bigelem">
</div>
<div class="project__card-design-bigelem">
</div>
</div>
Screen shot with Picture and text menu:
Screen shot with Picture and text menu
I will be grateful for any help!
Since I was looking for solutions that could identify the element with which number was highlighted. But so far I don’t even have ideas on how to do this.
All thanks in advance for any help!
If you like for this behaviour you can do this
hover: nav1 > imageNav1 ect...
You can get the index of the hover item and match that to the image nav item. Sorry for the markup, it's just to show you how you can implement it. You can also choose to do whatever after the matching is made in the mouseenter
$(".js-hover").on("mouseenter", function () {
const hoverIndex = $(this).index();
const $imageListItems = $(".image-list > li");
$imageListItems.removeClass("image-list__item--selected");
$imageListItems.eq(hoverIndex).addClass("image-list__item--selected");
});
.image-list__item--selected {
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="list">
<li class="js-hover">text</li>
<li class="js-hover">text</li>
<li class="js-hover">text</li>
<li class="js-hover">text</li>
</ul>
<ul class="image-list">
<li>image1</li>
<li>image2</li>
<li>image3</li>
<li>image4</li>
</ul>
Here's a solution with pure js, works for elements that are not parents using ids.
html
<li id="child1" onmouseenter="customHover(event)" onmouseleave="handlemouseleave(event)"></li>
<div id="parent1"> </div>
<li id="child2" onmouseenter="customHover(event)" onmouseleave="handlemouseleave(event)"></li>
<div id="parent2"> </div>
<li id="child3" onmouseenter="customHover(event)" onmouseleave="handlemouseleave(event)"></li>
<div id="parent3"> </div>
and heres the js
function customHover(e){
let id = e.target.id;
let idNumber = id.slice(id.length - 1);
document.getElementById(`parent${idNumber}`).style.border = '1px solid red';
}
function handleMouseLeave(e){
let id = e.target.id;
let idNumber = id.slice(id.length - 1);
document.getElementById(`parent${idNumber}`).style.border = 'unset';//or whatever you need to change the styles back to the original
}
there are many solutions , with an without using libraries. I think you may use some jquery if possible , and if not you should search for addeventlistener (the advanced way)
https://api.jquery.com/hover/
is a good example of doing what you are trying todo .
var pageitemcount=0;
$( ".page_item" ).hover(function() {
pageitemcount++;
$.post("/mypageitemcounter.php",{pageitemcount:pageitemcount});
$(this).parent().append( $( "<span>"+pageitemcount+"</span>" ) );
});
The above part is for php , still can be used in a plugin.
If you are in wordpress environment , you have to dig into how to write wp plugins also. Trying to achieve this in an environment , and then applying the same to your custom wp plugin is the way to go. Do not change the existing plugins, or themes if possible. This may cause headaches after an update.. In wp environment, writing a custom plugin is the way to go. You should tag your question as wp-plugin if possible.

Traverse down to the next element down not immediate and of different type

So in an html structure like this:
<a class="member-main">
<!-- other divs and html elements -->
</a>
<div class="hidden-group-item">
<!-- other divs and html elements -->
</div>
I want to bind a click event to an html element with class .member-main so to show a hidden element .hidden-group-item.
There are plenty of those elements repeated in the page in pairs so I'd also like to show only that .hidden-group-item immediately below its respective .member-main
I'm aiming to do so with a function like below, helped by this previous question:
$('body').on('click', '.member-main', function() {
$(this).next('.hidden-group-item')[0].toggleClass('hide')
});
I can get the element associated on click through this keyword (if I console log it), but I can't seem to grab that node that'd let me traverse down to the hidden-group-item.
How does this work in this case and what would be the most efficient way to achieve this?
...[0] returns a nodeElement not a jQuery object that has the function toggleClass. Try this:
$('body').on('click', '.member-main', function() {
$(this).next('.hidden-group-item') // next is already returning one item so no need to try to access the first
.toggleClass('hide')
});
This works as expected
The docs about the .next() method says the following:
Get the immediately following sibling of each element in the set of
matched elements. If a selector is provided, it retrieves the next
sibling only if it matches that selector.
Because you have the onClick handler and you're selecting the currently clicked element as $(this) then the matched set of elements is only the one you clicked, thus the next() call gets the .hidden-group-item just beneath it.
Sample
$('body').on('click', '.member-main', function() {
$(this).next('.hidden-group-item').toggleClass('hide')
});
.hide {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<a class="member-main">
<!-- other divs and html elements -->
hello
</a>
<div class="hidden-group-item hide">
<!-- other divs and html elements -->
hidden
</div>
<a class="member-main">
<!-- other divs and html elements -->
hello
</a>
<div class="hidden-group-item hide">
<!-- other divs and html elements -->
hidden
</div>
<a class="member-main">
<!-- other divs and html elements -->
hello
</a>
<div class="hidden-group-item hide">
<!-- other divs and html elements -->
hidden
</div>
JSFiddle

How to find the closest event element2 [duplicate]

This question already has answers here:
How to find the closest event element
(2 answers)
Closed 7 years ago.
I opened post where i asked for assistance with jquery code:
How to find the closest event element
unfortunately, other user didn't read my issue.
I have A link. clicking on it will show/toggle div. my problem is that my div is not always located at the same level from the A link. sometimes the A link is 1 level upon the hide DIV. sometime it's 2 levels or more. sometime it's below it
how can I find the closest DIV, that contain the class ".hidebox", to the A link?
<a href="#" class="hideBox-tab " >show div</a>
$(".hideBox-tab").click(function(){
$(this)
.parent().parent()
.find(".hideBox")
.toggle();
return false;
});
If you and an <a> to show/toggle the div the <a> must be outside the div:
toggle and show div
<div class="hideBox">
Content here
</div>
Then you need to find in your HTML one tag that allways englobes a.hideBox-tab and div.hideBox.
For example: div.partial-content:
<div class="partial-content">
toggle and show div
<div class="hideBox">
Content here
</div>
</div>
And your JS will be like this:
$(".hideBox-tab").click(function(){
$(this).closest(".partial-content").find(".hideBox").toggle();
});
I created a snippet, take a look at it:
$(".hideBox-tab").click(function(){
$(this).closest(".partial-content").find(".hideBox").toggle();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="partial-content">
toggle and show div
<div class="hideBox">
Content here
</div>
</div>
<div class="partial-content">
toggle and show div
<div>
<div class="hideBox">
Content 2 here
</div>
</div>
</div>
This solution works for one or more levels between a.hideBox-tab and div.hideBox.

Click button with hide and show

Need get this fixed as I've been trying for a month. Can you look at my website for the button that doesn't work?
http://www.insightenergy.eu/about-us.php
What is wrong with it?
try the following code to expand or minimize the container.
$('.expander').click(function(){
if(condition){
$('.expander').next().show();
}
else{
$('.expander').next().hide();
}});
You need to attach an event to your buttons, and when I debug I get nothing on click.
Looking at your web I think you maybe need something like that:
Your HTML structure is similar to this one:
HTML
<ul class="blog-post-full-list">
<li >
<div >0</div>
<div class="expandible">Content</div>
</li>
<li >
<div >1</div>
<div class="expandible">Content</div>
</li>
<li >
<div >2</div>
<div class="expandible">Content</div>
</li>
<li >
<div >3</div>
<div class="expandible">Content</div>
</li>
</ul>
So in your code you can use the JQuery function toggle:
JS
$(".blog-post-full-list>li").on('click',function(){
/*
*The object this is the li you've clicked on
*The jQuery function toggle swiches the display ON OFF
*The number 300 means the duration of the animation. If you don't
* want to animate it just remove the parametter
*/
$(this).find(".expandible").toggle(300);
})
http://jsfiddle.net/vzkUL/2/
You can add it into a JS file or inline in your code as follows:
<script>
//JQuery onReady
$(function(){
$(".blog-post-full-list>li").on('click',function(){
//The object this is the li you've clicked on
//The jQuery function toggle swiches the display ON OFF
//The number 300 means the duration of the animation. If you don't want to animate it just remove the parametter
$(this).find(".expandible").toggle(300);
})
});
</script>

multiple onclick's in HTML

I have a an HTML page with a list of 20 topics on it. I would like it so that when you click on one of those topics, 2 or 3 articles with links pop up underneath it.
I'm trying onclick but it means writing lots of code as you have to declare all the div styles for each of my topics.
Is there an easy way of doing this?
im currently writing this 20 times, and declaring 60 div styles:
<div class = "mousehand"
id = "show_first"
onclick ="this.style.display = 'none';
document.getElementById('show_second').style.display='block';
document.getElementById('dropdown').style.display='inline';
"> show text </div>
<div class = "mousehand"
id = "show_second"
onclick ="this.style.display = 'none';
document.getElementById('show_first').style.display='block';
document.getElementById('dropdown').style.display='none';
"> hide text </div>
<div id ="dropdown"> this is the text to be shown</div>
You can accomplish this with some Javascript. Add a ul within the li:
<li>Title
<ul>
...
</ul>
</li>
Set the inner ul's display to none using CSS. Then using Javascript, make a function that changes the display property of the inner ul to block.
As has been mentioned, jQuery can make this very straightforward, but your major code saving is going to come from taking advantage of event bubbling. You can do this is you structure your HTML something like this:
<div id="topics">
<div class="item">
<div class="show">
show text 1
</div>
<div class="hide">
hide text 1
</div>
<div class="text">
this is the text to be shown 1
</div>
</div>
<div class="item">
<div class="show">
show text 2
</div>
<div class="hide">
hide text 2
</div>
<div class="text">
this is the text to be shown 2
</div>
</div>
</div>
Now instead of attaching an onclick handler to each end every div, attach it to the parent element. To do this with jQuery:
$(window).load(function(){ //Do this when the page loads
$('#topics').bind('click', function(event) { //Find the element with ID 'topics' and attach a click handler
var t = $(event.target); //event.target is the element that was actually clicked, $() gets the jQuery version of it
if(t.hasClass('show')) { //If it is a 'show' element...
t.siblings('.hide').show(); //...show the other two elements...
t.siblings('.text').show();
t.hide(); //...and hide the clicked element
}
if(t.hasClass('hide')) { //If it is a 'hide' element...
t.siblings('.show').show(); //...show the 'show' element...
t.siblings('.text').hide(); //...and hide the other two
t.hide();
}
});
});
And that's it! Here's a demo.

Categories

Resources