I have a content like
<div id="sContainer">
<div class="message0" id="l0">Initial Content 111</div>
<div class="message1" id="l1">Initial Content 222</div>
<div class="message2" id="l2">Initial Content 333</div>
<div class="message3" id="l3">Initial Content 444</div>
<div class="message4" id="l4">Initial Content 555</div>
<div class="message5" id="l5">Initial Content 666</div>
<div class="message6" id="l6">Initial Content 777</div>
</div>
http://jsfiddle.net/LRLR/0sbdttds/
Even inside div, i have some more divs (not shown)
Is there any which to find which all divs are visible on screen ?
Requirement:
1. everytime div is focussed, i want to add css property
2. i need to store a variable
You can use the :visible property selector to fetch shown elements
$(function() {
var divs = $('[id^=l]:visible');
console.log('shown divs', divs);
alert('divs shown: ' + divs.length);
});
/* for testing purpose */
[id^=l] {
/* id starting with `l` */
display: none;
}
[id^=l]:nth-child(3n) {
/* every third element */
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="sContainer">
<div class="message0" id="l0">Initial Content 111</div>
<div class="message1" id="l1">Initial Content 222</div>
<div class="message2" id="l2">Initial Content 333</div>
<div class="message3" id="l3">Initial Content 444</div>
<div class="message4" id="l4">Initial Content 555</div>
<div class="message5" id="l5">Initial Content 666</div>
<div class="message6" id="l6">Initial Content 777</div>
</div>
Use Jquery Visible Selector With Starts With Selector
$("div[id^='l']:visible").addClass("Your_Class_Name");
You can use event delegation to find which element is being focused on. Please see this: http://jsfiddle.net/0sbdttds/1/
The key is to add a listener to the parent, like this:
$("#sContainer").click(showMessage);
Then in the handler, use the event to check the target, like this:
var focusedElement = $("#" + e.target.id);
focusedElement then contains a jQuery object that points to the element that was targeted by the action (which in the case of the fiddle is a click.)
The above fiddle works on clicks. If you want focus check out How to focus div?
Also, the CSS in your fiddle can be improved. It isn't DRY: http://csswizardry.com/2013/07/writing-dryer-vanilla-css/
The ids can be filtered out for visible elements using :visible pseudo selector. I have set tabIndex so that the <div>s are fucusable.
Please checkout the working code snippet below:
var dataAbc = '<div class="message7" tabindex="1">Focus Shifted Here</div>';
// I am prepending just 1 <div> as of now. To prepend multiple <div>s, make sure to increment the tabIndex using a for loop.
setTimeout(function(){ $(dataAbc).prependTo("#sContainer");},3000);
$("div:visible").each(function(){
console.log($(this).attr('id'));
});
$(document).on("focusin", "div div", function(){
$(this).css("background", "yellow");
});
$(document).on("focusout", "div div", function(){
$(this).css("background", "white");
});
.message0 {margin: 30px;height: 200px;border: 10px solid green;}
.message1 {margin: 30px;height: 200px;border: 10px solid yellow;}
.message2 {margin: 30px;height: 200px;border: 10px solid pink;}
.message3 {margin: 30px;height: 200px;border: 10px solid blue;}
.message4 {margin: 30px;height: 200px;border: 10px solid black;}
.message5 {margin: 30px;height: 200px;border: 10px solid cyan;}
.message6 {margin: 30px;height: 200px;border: 10px solid orange;}
.message7 {margin: 30px;height: 200px;border: 10px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="sContainer">
<div class="message0" id="l0" tabindex="2">Initial Content 111</div>
<div class="message1" id="l1" tabindex="3">Initial Content 222</div>
<div class="message2" id="l2" tabindex="4">Initial Content 333</div>
<div class="message3" id="l3" tabindex="5">Initial Content 444</div>
<div class="message4" id="l4" tabindex="6">Initial Content 555</div>
<div class="message5" id="l5" tabindex="7">Initial Content 666</div>
<div class="message6" id="l6" tabindex="8">Initial Content 777</div>
</div>
Updated jsFiddle
Checkout the documentation links below:
http://api.jquery.com/visible-selector/
https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement.tabIndex
To find the divs that are in the viewport requires a little more than what jQuery provides out of the box. You might need something like Viewport, which is a class I wrote for this kind of problem.
var viewport = new Viewport(window);
viewport.addEventListener("scroll:complete", function(vp) {
viewport.querySelectorAll("div.message", function(div) {
div.classList.add("foo");
});
});
Each div that you want to detect in the viewport should have one common class to make your code easier to maintain. Please note that Internet Explorer is supported starting at version 9, plus the normal standards compliant browsers.
I think that you looking for
$(document).ready(function(){
var i,classes;
var divs_num = $('#sContainer div').length;
for(i = 0 ; i < divs_num; i++){
Ids= $('#sContainer div:visible').eq(i).attr('id');
if(typeof Ids !== 'undefined'){
alert(Ids);
if(Ids == 'l3' ){
$('#'+Ids).css('background','blue');
}
}
}
$('#sContainer div').on('click',function(){
$('#sContainer div').css('border','5px solid blue');
$(this).css('border','5px solid red');
});
});
DEMO the code get all visible divs and alert all visible div Ids.. then check for example for id l3 if its visible change its background to red .. and in click event When click in any div change its border to red and change all another divs to blue border
Related
I am trying to use JavaScript to change the background color of an element after being selected, and also to make sure that only one element at a time has the particular background color. Once the user selects on a different element I would like the previous element that was selected to be replaced by a different background color. Currently I am only able to toggle individual elements by selecting on EACH element. I need to be able to select on an element and apply the new background color, then have JavaScript change the background color of the previously active element to a different color (one less click).
What I am trying to do is very similar to modern navbars or list items where only one element at a time is “active” and has a background color that is different than the other elements in the same div, row, etc.
Notes about my work I am utilizing bootstrap and have no desire to use jQuery for this particular project.
CSS:
<!DOCTYPE html>
<html lang="en">
<head>
<style>
h4 {
border: 1px solid black;
border-radius: 8px;
padding: 10px 2px 10px 2px;
margin: 20px 20px 0px 20px;
background-color: #F0F0F0;
border-color: #F8F8F8;
color: #505050;
cursor: pointer;
}
.active {
background-color: #99E6FF;
}
</style>
</head>
</html>
HTML:
<div id="pTwoRowOne">
<div class="row">
<div class="col-md-4 row row-centered">
<h4 id="techBio" class="test">Biology</h4>
</div>
<div class="col-md-4 row row-centered">
<h4 id="techCart" class="test">Cartography</h4>
</div>
<div class="col-md-4 row row-centered">
<h4 id="techChem" class="test">Chemistry</h4>
</div>
</div>
</div>
JavaScript:
document.getElementById("techBio").onclick=function() {
document.getElementById("techBio").classList.toggle('active');
}
document.getElementById("techCart").onclick=function() {
document.getElementById("techCart").classList.toggle('active');
}
document.getElementById("techChem").onclick=function() {
document.getElementById("techChem").classList.toggle('active');
}
An example can be seen here: http://jsbin.com/fugogarove/1/edit?html,css,js,output
If clarification is needed let me know.
Yup, pretty straightforward.
Assumptions
You're not trying to support IE8, since you're using classList
You're okay with housing your elements as variables as opposed to repeatedly querying the DOM.
Example
JSBin
Code
I rewrote your JavaScript to make it a little bit cleaner and to DRY it up a bit:
var techs = [].slice.call(document.querySelectorAll('#pTwoRowOne h4'));
function set_active(event) {
techs.forEach(function(tech){
if (event.target == tech) { return; }
tech.classList.remove('active');
});
event.target.classList.toggle('active');
}
techs.forEach(function(item) {
item.addEventListener('click', set_active);
});
Some explanation
[].slice.call(document.querySelectorAll('#pTwoRowOne h4')); – We're using this to change the output from a NodeList to an Array. This allows us to use forEach later. querySelectorAll returns a NodeList that contains all elements matching the CSS selector. You can probably replace that with a better CSS selector depending on your environment.
addEventListener is a much nicer way than the iterative add via onclick += to bind an event listener. It's also the recommended way (as far as I know) in ECMA5 and later.
By setting the element queries as variables, you'll be able to keep the reference in memory instead of polling the DOM every time to alter elements. That'll make your JavaScript marginally faster, and it's again just a nicer, cleaner version of the code which it produces.
updates
I reworked the JS to make more sense.
Assuming you only ever have one active element, you can find it using document.querySelector() - if you can have multiples you can use document.querySelectorAll() and iterate through them.
Simple case:
function activate(event) {
var active=document.querySelector('.active');
// activate the clicked element (even if it was already active)
event.target.classList.add('active');
// deactivate the previously-active element (even if it was the clicked one => toggle)
if (active) active.classList.remove('active');
}
document.getElementById("techBio").addEventListener("click",activate);
document.getElementById("techCart").addEventListener("click",activate);
document.getElementById("techChem").addEventListener("click",activate);
h4 {
border: 1px solid black;
border-radius: 8px;
padding: 10px 2px 10px 2px;
margin: 20px 20px 0px 20px;
background-color: #F0F0F0;
border-color: #F8F8F8;
color: #505050;
cursor: pointer;
}
.active {
background-color: #99E6FF;
}
<div id="pTwoRowOne">
<div class="row">
<div class="col-md-4 row row-centered">
<h4 id="techBio" class="test">Biology</h4>
</div>
<div class="col-md-4 row row-centered">
<h4 id="techCart" class="test">Cartography</h4>
</div>
<div class="col-md-4 row row-centered">
<h4 id="techChem" class="test">Chemistry</h4>
</div>
</div>
</div>
Another similar yet simpler way to do it: jsBin ;)
var H4 = document.getElementsByClassName("test"), act;
[].forEach.call(H4, function(el){
el.addEventListener("click", function(){
if(act) act.classList.remove("active");
return (this.classList.toggle("active"), act=this);
});
});
You can do something like this:
[].slice.call(document.querySelectorAll(".test")).forEach(function(element) {
element.addEventListener('click', function(event) {
if (activeElement = document.querySelector(".test.active")) {
activeElement.classList.remove("active");
};
event.target.classList.add('active');
});
});
Basically, first we remove the active class from the active element, then we add it to the target.
JSBin
I need something like a fill in the blanks sheet for children. When people click the ------ (dashes) it should turn into a textbox, and people can type it. after that when they move from that element after typing, it should turn into the text that they entered inside that text box.
I really dono how to approach this problem. I tried the following code, but what happens is, i am unable to type inside the text box. The cursor is not appearing at all
<html>
<head>
<title>NSP Automation</title>
<script src ="jquery.min.js">
</script>
</head>
<body>
<div class="container">
My Name is = <span id="name">__________<span>
</div>
<script>
$(document).on('click', '#name', function(){
document.getElementById("name").innerHTML = "<input type=\"text\">";
});
</script>
</body>
</html>
any pointers on how to achieve this ?
Thanks,
Since you've set the listener on the whole document, you will be recreating the input-tag with every click. Try something like:
$('#name').on('click', function(){
this.innerHTML = "<input type=\"text\">";
$('#name').off('click')
}
After clicking on the span-element, you remove the listener on it again, and you should be able to type.
http://jsfiddle.net/218rff9v/
Here is an example that generates the wished behaviour for all spans in your container. Some details can be improved but I think it's working as expected.
function convertSpanToInput() {
// Insert input after span
$('<input id="tmp_input">').insertAfter($(this));
$(this).hide(); // Hide span
$(this).next().focus();
$("#tmp_input").blur(function() {
// Set input value as span content
// when focus of input is lost.
// Also delete the input.
var value = $(this).val();
$(this).prev().show();
$(this).prev().html(value);
$(this).remove();
});
}
$(function() {
// Init all spans with a placeholder.
$(".container span").html("__________");
// Create click handler
$(".container span").click(convertSpanToInput);
});
Here is an html example with which you can test it:
<div class="container">
My Name is = <span></span>. I'm <span></span> years old.
</div>
JsFiddle: http://jsfiddle.net/4dyjaax9/
I'd suggest you have input boxes and don't do any converting
Simply use CSS to remove the borders and add a dashed border bottom
input[type=text]{
border:none;
border-bottom:1px dashed #777;
} <!-- something like that -->
add a click handler to add a edited class, so you can remove the bottom border
input[type=text].edited{
border:none;
}
That way you don't need to replace html elements, you just style them to look different
Why not use text input and only change CSS classes?
CSS:
.blurred{
border-style: none none solid none;
border-width: 0px 0px 1px 0px;
border-bottom-color: #000000;
padding: 0px;
}
.focused{
border: 1px solid #999999;
padding: 3px;
}
JavaScript:
$('#nameInput').focus(function(){
$(this).removeClass('blurred').addClass('focused');
});
$('#nameInput').blur(function(){
$(this).removeClass('focused').addClass('blurred');
});
HTML:
<div class="container">
My Name is = <span id="name"> <input id="nameInput" type="text" class="blurred"></input> <span>
</div>
Check this jsfiddle:
http://jsfiddle.net/gwrfwmw0/
http://jsfiddle.net/we6epdaL/2/
$(document).on('click', '#name', function(e){
if( $("#myText").is(e.target))
return;
$(this).html("<input type='text' id='myText' value='"+ $(this).html() +"'>");
});
$(document).on("blur", "#name", function(){
$(this).html( $("#myText").val() );
});
I don't have a table or ul structure for this but I am using divs to display data. I need the background color of every other row to be black. I looked around but most options are for tables or list menus so a bit puzzled as to how to do this. Any idea?
My structure:
<div class="container">
<div class="dataset">
Thomas Jones
</div>
<div class="dataset">
Edward Jones
</div>
<div class="dataset">
Tommy Lee
</div>
<div class="dataset">
Jenna Haze
</div>
</div>
You can do with with just CSS(3) using :nth-child(odd) (or even):
div.dataset:nth-child(odd) {
background: black;
}
jsFiddle example
i would go with CSS but in case you need it in jquery..then you can use :even or :odd selector.
try this
$('div:even').css('background-color','black'); // or just background , selects all even divs.
$('div:odd').css('background-color','black'); //selects all odd divs.
for just those divs having class dataset..add class selector to div. try this
$('div.dataset:even').css('background','black');
Use even/odd css3 selector
HTML
<div>row1</div>
<div>row2</div>
CSS
div {
width: 100px;
height: 20px;
border: 1px solid #ccc;
color: #fff;
}
div:nth-child(odd) {
background:red;
}
div:nth-child(even) {
background:black;
}
http://jsfiddle.net/sheeban/vHGzw/
If you must use jQuery for this:
$(".dataset").each(function(index){
if(index%2 == 0)
$(this).css('background', 'black');
});
jsFiddle
or use $("div.dataset:even").css('background', 'black');
jsFiddle
I'm struggling to find the right Jquery to show/hide a div at a height that is parallel to the trigger button. I attempted to offset the show/hide div to the right, but because the footnotes appear in different left/right positioning, each would be different. Instead, I will need to place the divs inside of another div along the right.
My hope is to add hyperlinked footnotes to some text, so that readers will not have to search for the footnotes, but also won't be overwhelmed with too much text. I would prefer to have more than one footnote open at a time, but if it needs to be one at a time to properly display, so be it.
EDIT:
#rohan-kumar helped with this code
$('.a_footnote').on('click',function(e){
e.preventDefault();
var divId=$(this).data('divid');
console.log(divId);
$('#'+divId).toggle();
});
So here's the way it stands: http://jsfiddle.net/6n28t/21/
However, my primary problem remains -- how can I make the footnote appear at the same height as the trigger? These will be long pieces of text and I want the footnotes to appear at the same height as the corresponding mark. How can I made [2] appear farther down on the page?
So, basically combining the other answers leads to this Fiddle
Html is the same as what you have in your fiddle.
CSS
.wrapp{
border:1px solid red;
height:100%;
}
.clear{
clear:both;
}
.footnotes div {
position: relative;
display: none;
}
JavaScript
$('.a_footnote').on('click',function(e){
e.preventDefault();
var divId=$(this).data('divid');
var height = $(this).position().top;
console.log(divId);
$(".footnotes div").hide();
$('#'+divId).toggle().css("top", height - 10);
});
You don't need the floats, I am assuming that you would want this text to appear inline in your paragraphs. You need to position the notes absolutely and then set the top/left according to the position of your clicked element + width of element + offset.
jsFiddle Demo
HTML:
<div class="content">
<p> Lorem ipsum ([1]).</p>
<p> Lorem ipsum ([2]).</p>
</div>
<div class="footnotes">
<div class="footnote1">1. Foo Bar</div>
<div class="footnote2">2. Foo Bar</div>
</div>
CSS
.footnotes > div { display: none; position: absolute; border: solid 1px red; }
JavaScript
$('.footnote').on('click', function(e) {
e.preventDefault();
var $note = $('.' + this.id);
var $position = $(this).position();
$('.footnotes > div').hide();
$note.css({
top : $position.top,
left: $position.left + $(this).width() + 5
}).show(); })
Try this,
HTML
<div class="wrapp">
<div class="content" style="float:left;">
<div> Lorem ipsum (<a class="a_footnote" href='javascript:;' data-divid="footnote1">[1]</a>).</div>
</div>
<div class="footnotes" style="float:right">
<div id="footnote1">1. Foo Bar</div>
</div>
<div class="clear"></div>
</div>
CSS
.wrapp{
border:1px solid red;
height:50px;
}
.clear{
clear:both;
}
SCRIPT
$('.a_footnote').on('click',function(e){
e.preventDefault();
var divId=$(this).data('divid');
console.log(divId);
$('#'+divId).toggle();
});
If you want the div.footnotes will be hidden initially, then you need to add a css like
div.footnotes {display:none;}
Fiddle http://jsfiddle.net/6n28t/7
HTML:
<div class="container" style="width:200px; height: 200px; border: 10px solid #ccc">
contents..
</div>
JQUERY:
$('.container').hover(function() {
console.log('in');
},
function() {
console.log('out');
});
It makes console.log when hover occurs both on border and div.
Objectives:
1> Want to make a `hover` event only for `div`, but not for `border`.
2> Fire another `hover` event on `border`, but not for `div`
Are the possible? if, then I want your cordial help..
A pragmatic solution would be to:
<div class="container" style="width:200px; height: 200px; border: 10px solid #ccc">
<div class="inner" style="height: 200px;">
contents..
</div>
</div>
and
$('.container .inner').hover(function() {
console.log('in');
},
function() {
console.log('out');
});
Cleanest option imo. a javascript solution would be more complex and simply not worth it.
The border IS the div, at least in part.
There's no event for specifically hovering over a border that I know of.
What you can do is have a nested div (within another div) and have a 10px padding on the internal one. This will give you 2 divs to work with and apply hover events to as well as looking the way you require.
Working example: http://jsfiddle.net/jssSA/
HTML
<div id="outer">
<div id="inner">Some content</div>
</div>
CSS
#outer,#inner{width:300px; height:300px;}
#outer{
background-color:#000;
padding:10px;
}
#inner{
background-color:#ccc;
}
jQuery
$('#outer').hover(function(){
console.log("outer in")},
function(){console.log("outer out")});
$('#inner').hover(function(){
console.log("inner in")},
function(){console.log("inner out")});