How to stop event when user clicks inside certain divs using JavaScript - javascript

I want this code to check if the user has clicked inside the open box and if so then it will keep it open, also if the user clicks outside the box it will close.
http://jsfiddle.net/MTJa5/26/
var boxes = function(){
var divClicks = document.getElementsByClassName("clickToShow");
for(i=0; i < divClicks.length; i++){
var click = divClicks[i];
var clickEvent = function(){
click.addEventListener("click", function(e){
var currentClass= this.getElementsByTagName('div')[0].className;
var divs = document.getElementsByClassName('openedBox');
for(var i = 0; i < divs.length; i++){
divs[i].setAttribute("class", "closedBox");
}
if(currentClass === "openedBox"){
this.childNodes[3].setAttribute("class", "closedBox");
} else {
this.childNodes[3].setAttribute("class", "openedBox");
}
},false);
}();
}
}();

Instead of binding several event listeners, you can also bind just one click event, and use the event.target property to check where you've clicked.
The updated code is less comples, and easier to maintain.
Demo: http://jsfiddle.net/MTJa5/28/
var hellos = function() {
function closeAllButThisBox(targ) {
var allBoxes = document.getElementsByClassName('openedBox');
for (var i=allBoxes.length-1; i>=0; i--) {
if (allBoxes[i] !== targ) {
allBoxes[i].className = 'closedBox';
}
}
}
window.addEventListener('click', function(ev) {
var targ = ev.target;
// Traverse the tree, until you hit the desired / root element
while (targ && targ !== document.documentElement) {
if (targ.className.indexOf('openedBox') !== -1) {
closeAllButThisBox(targ);
// Do nothing when clicking inside an opened box
return;
}
// This will open boxes, if closed, when clicking at the <p>
if (targ.tagName.toLowerCase() === 'p' && targ.parentNode.className.indexOf('clickToShow') !== -1) {
closeAllButThisBox(targ.parentNode);
targ.parentNode.getElementsByTagName('div')[0].className = 'openedBox';
return;
}
targ = targ.parentNode;
}
// At this point, the click is not at the right place.
// Close all boxes by removing the closedBox class names
var boxes = document.getElementsByClassName('openedBox');
for (var i=boxes.length-1; i>=0; i--) {
boxes[i].className = 'closedBox';
}
}, false);
}();

Related

Adding onClick function to select elements

I have a select tag of dynamically added elements. I need to add an event listener to each of the elements in the select tag except the first which:
adds the text of the element to a list,
makes the focus of the list the first element again, and
removes or hides the clicked element.
The first element is a 'none' element which doesn't need any event listener.
I've tried something like
for (var i = 0; i < array.length; i++)
{
var name = array[i];
var selectElement = document.getElementById(selectElementId);
addToSelectNode(document.getElementById(selectElementId), name);
var thisNode = selectElement.childNodes[i];
if (thisNode.value != "none")
{
thisNode.addEventListener("click", function(event)
{
appendNodeToList("artist-list", i);
selectElement.selectedIndex = 0;
selectElement.remove(selectElement.i);
selectElement.style.display = "none";
});
}
}
function addToSelectNode(element, optionText)
{
var newSelectElement = document.createElement("option");
newSelectElement.text = optionText;
element.add(newSelectElement);
}
function appendNodeToList(listId, text)
{
var newNode = document.createElement("LI");
var textNode = document.createTextNode(text);
newNode.appendChild(textNode);
document.getElementById(listId).appendChild(newNode);
}
Didn't work at all though
A few hours later I've solved my own question. The problem stemmed from trying to remove items in the select tag which just wasn't working - I'm nut sure if it's possible but making it disabled solved it. Anyway here's the result.
HTML:
<select id="artist-select-list">
<option value="none">none</option>
</select>
JavaScript:
window.onload = function()
{
var dropdown = document.getElementById("sampleDropdown");
var n = array.length;
// Loop to add to <select> dropdown
for (var i = 1; i <= n; i++)
{
addToSelectNode(dropdown, array[i - 1]);
}
// Loop to add id's to each element in the dropdown
for (var i = 0; i <= n; i++)
{
dropdown[i].id = "selectNum" + i;
}
// Loop to add event listener
for (var i = 0; i < dropdown.length; i++)
{
dropdown[i].addEventListener("click", function(event)
{
// Regardless of which option the user clicks move shown option to "none" (first index in dropdown)
dropdown.selectedIndex = 0;
if (event.target.id != "selectNum0")
{
// Disable once clicked
event.target.disabled = true;
// Do other things here in relation to event.target
}
});
}
}
var array =
[
"sampleText1", "sampleText2"
];
function addToSelectNode(element, optionText)
{
var newSelectElement = document.createElement("option");
newSelectElement.text = optionText;
element.add(newSelectElement);
}

Simple shortening of my code

I am looking for a way to simplify this code using for loops. Any help is appreciated.
I am setting up a system of opening modal frames full of images when somebody clicks on a link with a date on it (e.g. a photo archive). I have a lot of different dates and each time I make a new one I have to insert it a million times into the code as shown below. Maybe I could make an array of some sort that holds the dates and loop through the array and generate the code below. There is probably a simple fix to this, but I am new to web development. Thanks!!!!
// Get the modal gallery
var gallery161207 = document.getElementById('gallery161207');
var gallery161130 = document.getElementById('gallery161130');
...
var gallery150916 = document.getElementById('gallery150916');
// Get the close button
var closeButton161207 = document.getElementById('closeModal161207');
var closeButton161130 = document.getElementById('closeModal161130');
...
var closeButton150916 = document.getElementById('closeModal150916');
// Get the buttons
var btn161207 = document.getElementById('161207');
var btn161130 = document.getElementById('161130');
...
var btn150916 = document.getElementById('150916');
// When the user clicks on the button, open the modal gallery
function openGallery(source) {
// Open the modal gallery depending on what was clicked
if (source == '161207')
gallery161207.style.display = "block";
if (source == '161130')
gallery161130.style.display = "block";
...
if (source == '150916')
gallery150916.style.display = "block";
}
// When the user clicks on <span> (x), close the modal
closeButton161207.onclick = function() {
gallery161207.style.display = "none";
}
closeButton161130.onclick = function() {
gallery161130.style.display = "none";
}
...
closeButton150916.onclick = function() {
gallery150916.style.display = "none";
}
btn161207.onclick = function() { openGallery('161207'); }
btn161130.onclick = function() { openGallery('161130'); }
...
btn150916.onclick = function() { openGallery('150916'); }
window.onclick = function(event) {
if (event.target == gallery161207) {
closeButton161207.onclick();
}
if (event.target == gallery161130) {
closeButton161130.onclick();
}
...
if (event.target == gallery150916) {
closeButton150916.onclick();
}
}
You could do this fairly easily using jQuery, but I assume, since you're new to web development, you'll want to start out from scratch.
First, let's deal with setting up the buttons to show the galleries. I'd say you give each button a class="gallery-button" attribute and an id="<id of gallery>". The galleries also should have IDs id="gallery-<id of gallery>". Then:
var buttons = document.getElementsByClassName("gallery-button");
for(var i =0; i < buttons.length; i++){
var elem = buttons[i];
elem.onclick = function() {
document.getElementById('gallery' + elem.id).style.display="block";
};
}
}
We can do a similar thing for the close buttons (assuming they have IDs of id="close-<id of gallery>" and their class="close-button":
var closeButtons = document.getElementsByClassName("close-button");
for(var i =0; i < buttons.length; i++){
var elem = closeButtons[i];
elem.onclick = function() {
document.getElementById('gallery-' + elem.id.replace("close-", "")).style.display="none";
};
}
}
And then:
window.onclick = function(event) {
var id = event.target.id;
if (id.startsWith("gallery-") {
var closeButton = document.getElementById("close-" + id.replace("gallery-", ""));
closeButton.onclick();
}
}
You can try making an object saving all the dom references and using those. This answer makes use of jQuery for its document ready function.
var sourceList = [];
var sources = {};
var wrappers = document.getElementsByClassName('gallery-wrapper');
for(var i = 0; i < wrappers.length; i++){
sourceList.push(wrappers[i].id);
}
$( document ).ready(function() {
for(var i = 0; i < sourceList.length; i++){
var source = {};
source.gallery = document.getElementById("gallery"+sourceList[i]);
source.button = document.getElementById("button"+sourceList[i]);
source.closeButton = document.getElementById('closeButton'+sourceList[i]);
source.button.onclick = function() {
if(source.gallery)source.gallery.style.display = "block";
}
source.closeButton.onclick = function() {
if(source.gallery)source.gallery.style.display = "none";
}
sources[sourceList[i]] = source;
}
window.onclick = function(event) {
for (var source in sources)
if (event.target == sources[source].gallery)
sources[source].closeButton.onclick();
}
});

How do I auto click an options drop down?

Here is the code that I have. It does select the option, but it does not click on it. I need it to click on the option or it will not work with the rest of my script. Any way of actually simulating a click?
//Country
function setOption(selectElement, value) {
var options = selectElement.options;
for (var i = 0, optionsLength = options.length; i < optionsLength; i++) {
if (options[i].value == value) {
selectElement.selectedIndex = i;
return true;
}
}
return false;
}
setOption(document.getElementById('billCountry'), Co);
//State
function setOption(selectElement, value) {
var options = selectElement.options;
for (var i = 0, optionsLength = options.length; i < optionsLength; i++) {
if (options[i].value == value) {
selectElement.selectedIndex = i;
return true;
}
}
return false;
}
setOption(document.getElementById('billState'), Sa);
Thank you for the help.
Sounds like the problem is in the rest of your script and you may want to consider changing it to not rely on a click. Consider using a "change" event. If you really need to fire a click event something like this should do it:
var element = document.getElementById('foo');
var e = document.createEvent('MouseEvents');
e.initEvent('click', true, true);
element.dispatchEvent(e);

javascript menu, How to close when mouse outside of div?

this is my first pure JavaScript script as you can probably tell, by the length of it! I'm at a loss to workout how i can get the child links which are in a div with a class called 'menu' to close when i leave that div.
I've tried to write an If argument to set it to close when i leave the 'A' and also a 'DIV' and that doesn't seem to work?
Any help would be much appreciated and sorry for the overly long code!
Please no Jquery for now, thanks!
<script>
// Variables
var getFirstMenu = document.getElementsByTagName('div');
// Use selectors
var getMenuClasses = document.getElementsByClassName('menu');
// Hide drop down menus
for(var i=0; i < getFirstMenu.length; i++){
getFirstMenu[i].style.visibility = 'hidden';
}
// =============================
// Show Menu on mouseover
function showDropdown(e){
var el = e.target;
if(el.nodeName == 'A'){
for(var i = 0; i < getMenuClasses.length; i++) {
if(el == getMenuClasses[0]){
getFirstMenu[0].style.visibility = 'visible';
}else if(el == getMenuClasses[1]) {
getFirstMenu[1].style.visibility = 'visible';
}else if(el == getMenuClasses[2]){
getFirstMenu[2].style.visibility = 'visible';
}
}
}
}
var getMainMenu = document.getElementById('menu');
getMainMenu.addEventListener('mouseover', function(e){
showDropdown(e);
},false);
// =============================
// Hide Menu on mouseout
function mouseOutMenu(e){
var el = e.target;
if(el.nodeName == 'DIV')
for(var i = 0; i < getFirstMenu.length; i++){
getFirstMenu[i].style.visibility = 'hidden';
}
}
getMainMenu.addEventListener('mouseout', function(e){
mouseOutMenu(e);
}, false);
Add a Handler to the document-object
document.addEventHandler('mouseover', function(){
// close it
}, false);
Or when this is about to hide a submenu: Add the handler to the menu which then hides the menu on mouseover
Look Demo
Code :
// Variables
var getFirstMenu = document.getElementsByTagName('div');
// Use selectors
var getMenuClasses = document.getElementsByClassName('menu');
// Hide drop down menus
for(var i=0; i < getFirstMenu.length; i++){
getFirstMenu[i].style.visibility = 'hidden';
}
// =============================
// Show Menu on mouseover
function showDropdown(e){
var el = e.target;
if(el.nodeName == 'A'){
for(var i = 0; i < getMenuClasses.length; i++) {
if(el == getMenuClasses[0]){
getFirstMenu[0].style.visibility = 'visible';
}else if(el == getMenuClasses[1]) {
getFirstMenu[1].style.visibility = 'visible';
}else if(el == getMenuClasses[2]){
getFirstMenu[2].style.visibility = 'visible';
}
}
}
}
var getMainMenu = document.getElementById('menu');
getMainMenu.addEventListener('mouseover', function(e){
showDropdown(e);
},false);
// =============================
// Hide Menu on mouseout
function mouseOutMenu(e){
var el = e.target;
//if(el.nodeName == 'A')
for(var i = 0; i < getFirstMenu.length; i++){
getFirstMenu[i].style.visibility = 'hidden';
}
}
for(var i = 0; i < document.getElementsByTagName('div').length; i++){
document.getElementsByTagName('div')[i].addEventListener('mouseout', function(e){
mouseOutMenu(e);
}, false);
}

Link change in textbox

I am trying to create a script where a user clicks on the link type he wants and it opens it up in a small textfield below based on which he clicks.
For example
How can i create something like this where the user clicks on the link he wishes and it will change that textfield on click to which he desires?
Assuming the following mark-up style:
<ul>
<li><a class="linkInsert" href="http://www.example.com/article/">Link (email & blogs)</a></li>
</ul>
<input id="linkText" />​
Then you can use plain JavaScript:
var links = document.getElementsByTagName('a'),
textInput = document.getElementById('linkText'),
linkInserts = [];
for (var i = 0, len = links.length; i < len; i++) {
if (links[i].className == 'linkInsert') {
linkInserts.push(links[i]);
}
}
for (var i = 0, len = linkInserts.length; i < len; i++) {
linkInserts[i].onclick = function(e) {
e.preventDefault();
textInput.value = this.parentNode.innerHTML;
};
}​
JS Fiddle demo.
Or, with jQuery:
$('a.linkInsert').click(
function(e){
e.preventDefault();
$('#linkText').val($(this).parent().html());
});​​​​​​​​​​​​​​​​​​
JS Fiddle demo.
Changed the above HTML to the following, in order to avoid redundant attributes in the pasted HTML and then having to filter them back out, so now targeting the parent li element:
<ul>
<li class="linkInsert">Link (email & blogs)</li>
</ul>
<input id="linkText" />​
jQuery:
$('li.linkInsert a').click(
function(e){
e.preventDefault();
$('#linkText').val($(this).parent().html());
});​
JS Fiddle demo.
And the plain-JavaScript version updated to use the amended HTML:
var listElems = document.getElementsByTagName('li'),
textInput = document.getElementById('linkText'),
linkInserts = [];
for (var i = 0, len = listElems.length; i < len; i++) {
if (listElems[i].className == 'linkInsert') {
linkInserts.push(listElems[0].getElementsByTagName('a')[0]);
}
}
for (var i = 0, len = linkInserts.length; i < len; i++) {
linkInserts[i].onclick = function(e) {
e.preventDefault();
textInput.value = this.parentNode.innerHTML;
};
}​
JS Fiddle demo.
And using a slightly more up-to-date approach, with addEventListener():
function showHTML(evt){
evt.preventDefault();
var textInput = document.getElementById('linkText'),
target = evt.target,
targetTag = target.tagName.toLowerCase();
if (targetTag == 'a'){
textInput.value = target.parentNode.innerHTML;
}
else if (targetTag == 'li'){
textInput.value = target.innerHTML;
}
}
document
.getElementsByTagName('ul')[0]
.addEventListener('click',function(evt) { showHTML(evt) },false);
JS Fiddle demo.
And, finally, a version that seems compatible with ancient 'legacy' Internet Explorer (tested on IE 8, WinXP and IE 9, Win7):
function showHTML(evt) {
var evt = evt || event;
if (evt.preventDefault){
evt.preventDefault();
}
else {
event.returnValue = false;
}
var textInput = document.getElementById('linkText'),
target = evt.target ? evt.target : evt.srcElement,
targetTag = target.tagName.toLowerCase();
if (targetTag == 'a') {
textInput.value = target.parentNode.innerHTML;
}
else if (targetTag == 'li') {
textInput.value = target.innerHTML;
}
}
if (window.addEventListener) {
document.getElementsByTagName('ul')[0].addEventListener('click', function(evt) {
showHTML(evt)
}, false);
}
else if (window.attachEvent) {
document.getElementsByTagName('ul')[0].attachEvent('onclick', showHTML);
}​
JS Fiddle demo.
References:
addEventListener().
attachEvent().
event.preventDefault().
event.returnValue (an explanation, of sorts, discovered via Google, here on Stack Overflow).
getElementById().
getElementsByTagName().
push().
Make the links go nowhere, e.g #, give them an id, listen to click on thees with jquery or Use the onclick html attribute, select the area and set the clicked link text :-)

Categories

Resources