so I have a javascript function that changes the class name of a div
function flip (event)
{
var element = event.currentTarget;
element.className = (element.className == 'card') ? 'card flipped' : 'card';
}
How can I make it so my onclick="flip(event)" can be attached to a button (or preferably an image) and the button will then flip the card instead of just clicking inside the div. So something like
<div id="card" class="card">
<p>
whatever
</p>
<img onclick="flip(event)" src="foo">
</div>
What do I need to change in my javascript function?
This should work
<img onclick="javascript:flip('card');" />
function flip (elementId)
{
var element = document.getElementById(elementId)
element.className = (element.className == 'card') ? 'card flipped' : 'card';
}
I'm not sure but I think that John solution's can have problem if you have several elements with class 'card' and you only want to change the one that was clicked.
To do this, use 'this' as argument :
<img onclick="javascript:flip(this.parentElement);" />
function flip (element)
{
element.className = (element.className == 'card') ? 'card flipped' : 'card';
}
$('imgSelector').click(function() {
$(".card").toggleClass('card flipped');
});
Using jQuery you can do it Like this.
with Simple javascript you will have to give a id to your DIV. and then instead of using event.target just simply use document.getElementById('myDIVID');
the event object has a reference to the element that originated the event.
you can use parentNode to work back up the tree.
this will work with your html example.
function flip (event)
{
var image = event.target || event.srcElement;
var div = image.parentNode;
div.className = (div.className == 'card') ? 'card flipped' : 'card';
}
target is the originating element in ff/chrome, srcElement is the same element in IE. currentTarget in ff/chrome is the element which called the handler, which may not be the same element you clicked on. for example, if you attached a click handler right on the div, it would fire when you clicked on the image within. when the div's handler fires, currentTarget would be the div and target would be the image. IE has no parallel for currentTarget that i'm aware of.
Related
I'm trying to close an element when I detect a click outside of the element itself, but it seems to be closing the element anyway whenever I click on it.
EDIT: Figured it out.
You have an error in your code, var container = $(".nav-container"); should be var container = $("#nav-container"); you are searching for nav-container as a class rather than an id, # = id, . = class
Try this script.
you are using class (var container = $(".nav-container");) instead of id var container = $("#nav-container"); here
$(document).mouseup(function (e) {
var container = $("#nav-container");
if (!container.is(e.target) && container.has(e.target).length === 0) {
$('#nav-container').removeClass('open-nav');
$('#mask').removeClass('active-mask');
$('body').removeClass('no-overflow');
}
});
I am trying to make a tooltip with content disappear when I click outside it, but tried solutions to different posts and none of those solutions work for me.
I think the problem is how I am triggering the tooltip, but is the only way I know, here is the code I have in my js and my html markup.
The tooltip fires well, but it doesn't work with the blur event in any way I tried.
$(document).ready(function() {
function tooltover(target_item){
$(target_item + '> a').click(function(){
$('.tiptover_box').focus();
var pos = $(this).position();
var width = $(this).outerWidth();
var boxw = $(this).next().outerWidth();
var boxh = $(this).next().outerHeight();
$(this).next().css('left', (pos.left - ((boxw/2)-(width/2))));
$(this).next().css('top', (pos.top - (boxh+5)));
$(this).next().addClass('tiptover_show');
$(this).next().delay(5).queue(function(){
$(this).addClass('tt-in');
$(this).dequeue();
});
});
$('.tiptover_box').blur( function(){
$('.tiptover_box').removeClass('tiptover_show tt-in');
});
} tooltover('.tiptover');
});
And HTML
<div class="tiptover">
<a>Link Test</a>
<div class="tiptover_box" style="background-image: url(content/prod_0002.jpg);">
<div>Description.</div>
</div>
</div>
A different approach would be to not focus on the div itself, but focus on the rest of the DOM.
In this solution given by prc322 on a similar question he used the mouseup event on the document itself:
$(document).mouseup(function (e)
{
var container = $(".tiptover_box");
if (!container.is(e.target) // if the target of the click isn't the container...
&& container.has(e.target).length === 0) // ... nor a descendant of the container
{
container.removeClass('tiptover_show tt-in');
}
});
(edited by me for relevance)
Now your tooltip will be "closed" whenever a mouseup event fired on any element that is not the .tiptover_box or any of its descendants.
Instead of trying to trigger the blur event of a div (which is not as reliable as blurring an input field), you can do what you say you want - when anything is clicked, you hide the tooltip:
$('body').click(function(e){
var tooltipContainer = $('.tiptover_box');
var clickTarget = e.target;
if(!tooltipContainer.is(clickTarget)
&& tooltipContainer.has(clickTarget).length === 0){
tooltipContainer.removeClass('tiptover_show tt-in');
}
});
edit: added test for container and its children, basically same as the answer from Bob.
In my Div (Code Below) there is an onClick function that triggers the visibility of a second div, and there is also a content edible in the div as well. When I click to change the text it also triggers the visibility of the second div. How would I change the code so that I can click the text without changing the second div's visibility?
<div class="div1" id ="div1" onclick="onStepClicked()" style ="text-align:center"><p contenteditable="true" >Step 1</p></div>
Function:
function onStepClicked() {
var elem = document.getElementById('div2');
if (Visible === true) {
elem.style.display = 'none';
Visible = false;
}
else {
if (Visible === false) {
elem.style.display = 'block';
Visible = true;
}
}
}
You may trigger the click on the Parent div only and exclude the click on child in jQuery like this:
$("#div1").click(function(){
$("#div2").css('visibility','hidden');
}).children().click(function(e) {
return false;
});
If you are not OK with jQuery and are after a JavaScript - only solution, please leave a comment and let me know.
UPDATE
If you are after a JavaScript solution, here U R:
HTML
<div id ="div1" onclick="onStepClicked()" >
<p id="editable" contenteditable="true">Step 1</p>
</div>
JS
function onStepClicked(){
document.getElementById('div1').onclick = function(e) {
if(e.target != document.getElementById('editable')) {
document.getElementById('div2').style.visibility = 'hidden';
}
}
}
Try using the element>element selector in your script. It will only affect the first child element and then stop from affecting sub-child elements.
Tutorial:
(http://www.w3schools.com/cssref/sel_element_gt.asp)
I wrote the code below to dynamically add li elements to a ul element. I want the user to be able to click on any one of them and have that li item removed. I know how to do this with JQuery but I want to know how to do it with vanilla JavaScript.I understand that removeChild() is the only method at my dispose to do this but I am a bit confused as to how to use it to accomplish the task at hand.
Thank you.
http://jsfiddle.net/3wk0866o/
HTML
<form id="input-form">
<input id="input-field" type = "text"/>
<button>Submit</button>
</form>
<ul id="list" >
</ul>
JavaScript
var form = document.getElementById("input-form");
function getInput(event){
event.preventDefault();
var inputValue = document.getElementById("input-field").value
form.reset();
document.getElementById("list").innerHTML += "<li>"+ inputValue +"</li>";
}
form.addEventListener("submit",getInput,false)
Try this:
http://jsfiddle.net/3wk0866o/1/
I just added this listener function:
function removeItem(e) {
var target = e.target;
if(target.tagName !== 'LI') return;
target.parentNode.removeChild(target);
}
list.addEventListener('click', removeItem);
It adds an event listener to the "list" UL element, and listens for clicks inside of it. e.target is the element clicked, and if the element clicked isn't a LI element, then the function just returns. If it is, then it removes the element and all of its children.
If you want to know how the last bit that removes the element works:
target.parentNode finds the parent element of the clicked LI element (UL), and then you just simply call removeChild on that node, since LI is a child element of UL. You can also use the remove method on the element directly, but that is not well supported yet.
Note that you might run into problems if your LI element has children; in that case, the target might show up as one of LI's children and not as LI. To solve that you can use a loop that walks through the DOM until it gets to an UL element, or until it finds a LI element to remove:
http://jsfiddle.net/3wk0866o/3/
function removeItem(e) {
var target = e.target;
while(target.tagName !== 'UL') {
if(target.tagName === 'LI') {
return target.parentNode.removeChild(target);
}
target = target.parentNode;
}
}
list.addEventListener('click', removeItem);
If your LI elements will only have text inside of them, then the first solution is enough.
Good luck.
You could add an onclick event listener directly to the new child.
function getInput(event){
event.preventDefault();
var inputValue = document.getElementById("input-field").value
console.log(inputValue)
form.reset(); // _______________Reset method
// Create new element.
var new_li = document.createElement('li');
new_li.innerHTML = inputValue;
// When it is clicked, remove it.
new_li.onclick = function() {
this.remove();
};
// Append element as child to list.
document.getElementById("list").appendChild(new_li);
}
JSFiddle
you can use parent.removeChild(child) to remove the item but you might have problem with finding the child because the item has been added on the fly.
2 suggestion:
add the item in the list as you add them to the list and then grab them from the list instead of finding them on the page.
use .On function to attach click event and then use this in the event to grab them.
I am working with a nested click event (there is a large array of images, some with children images, some without).
Onclick for all of the images (children, parent and non-parent), they should display in a diff css div, and then remove themselves if clicked again, indefinitely.
So far this code works for the parent and non-parent images, but bubbling is making the children images display the parent images instead.
If I return false to stop the bubbling before the children function, it will break the functionality for the parent and non-parent images that are further down in the array (the children are in a new popup css, not a list), but if I don't stop the bubbling, the nested click event won't run.
Anyone see a good way around this mess?
// Click an image, and it will change it in the demo css class panel
$('.item-button').data('status','not_clicked');
$('.item-button').click(function(event) {
var layerID = $(this).attr('data-layer'); //these do not correspond to actual layers of nesting.
var itemID = $(this).attr('data-item');
var itemmulti = $(this).attr('data-multi'); //this value def works to recognize parent from other non-parent items (not children).
var clayerID = $(this).attr('data-clayer');
var citemID = $(this).attr('data-citem'); //child item 1.
if(( $(this).data('status') == 'clicked') || itemID == 0) {
var imageSrc = $(this).parent().find('img').attr('id');
$(layerID).attr('src', imageSrc);
} else {
$(this).data('status','clicked');
var imageSrc = $(this).parent().find('img').attr('id');
$(layerID).attr('src', imageSrc);
if (itemmulti != 0) {
//begin headache.
document.getElementById('child-' + itemID).style.display = "inline-block";
//this is where a separate click function for children items begins.
$('.item-sub1').data('status','unclicked');
$('.item-sub1').click(function(event) {
if(( $(this).data('status') == 'click') || citemID == 0) {
var imageSrc = $(this).parent().find('img').attr('id');
$(selector).attr('src', imageSrc);
} else {
$(this).data('status','click');
var imageSrc = $(this).parent().find('img').attr('id');
$(clayerID).attr('src', imageSrc);
}
return false;
});
}
}
});
<img button title id alt />
<input radio id="layer-{ID}-{item.ID}-radio" name="layer-{ID}" value="{item.ID}" class="item-button" data-multi="{item.PARENT}" data-layer="{ID}" data-item="{item.ID}" />
<!-- IF item.CHILD1 != 0 -->
<div id="child-{item.ID}" style="width: 300px; position: absolute; display: none;">
<img button here title data-layer="{item.CLAYER1}" data-item="{item.CHILD1}">
<input radio id="layer-{item.CLAYER1}-{item.CHILD1}-radio" name="layer-{item.CLAYER1}" value="{item.CHILD1}" style="display: none;" class="item-sub1" data-clayer="{item.CLAYER1}" data-citem="{item.CHILD1}" />
I think what you need to do to prevent the event from bubbling up the DOM tree and preventing any parent handlers from being notified of the event is to use stopPropagation() method.
$('.item-button').click(function(event) {
event.stopPropagation();
// your code...
For more info:
1. jquery
2. javascript