Javascript onblur/onfocus - javascript

I am having some trouble with the two events, they work fine, however I have ran into a problem:
I have a div inside of a div. When the inner div is in focus, I want a set of style buttons to be appended to the outer div. However when i try to click on the buttons, it unfocuses the inner div and makes the buttons go away. I want them to go away when focus is lost but I dont want focus to be lost when I press a button. Sorry if this is a little confusing here is some code and a jsfiddle of it in action:
function addButtons() {
var node = document.createElement('div');
var obj = document.getElementById('container');
node.setAttribute('id', 'buttons');
node.innerHTML = '<input type="button" value="B" onClick="document.execCommand(\'bold\',false)" />';
obj.appendChild(node);
}
function removeButtons(id) {
var obj = document.getElementById('container');
obj.removeChild(obj.childNodes[3]);
}
http://jsfiddle.net/bnjGE/2/
If I remove the removeButtons() function, it works fine, but multiple buttons will be created.
I can try to clear things up, just ask.
Thankyou

You can add a return false; statement on the mousedown event on the button, f.ex:
node.getElementsByTagName('input')[0].onmousedown = function(e) {
return false;
};
http://jsfiddle.net/bnjGE/8/

document.onclick = function(e){
console.log(e.target);
if(e.target.id != 'buttons' && e.target.parentNode.id != 'buttons' && e.target.id != 'textarea'){
removeButtons();
}
}​
http://jsfiddle.net/bnjGE/7/
Maybe this is a solution,but not perfect.

Related

Problem with changing button text content

I'm making a battleship game in Javascript and I have a problem with a function that changing button text content. I want to do that when the user click the button the text content of the button changes.
function changePosition(eventBtn){
if(eventBtn.target.textContent=='perpendicularly'){
eventBtn.target.textContent='horizontally';
}
else{
eventBtn.target.textContent='perpendicularly';
}}
But when I click on the button nothing changes. I think the problem is with the else statement because when I delete this statement all work.
Make sure that you are adding the listener to the button appropriately.
function changePosition(event) {
if (event.target.textContent === 'Perpendicularly') {
event.target.textContent = 'Horizontally';
} else {
event.target.textContent = 'Perpendicularly';
}
}
document.querySelector('.direction').addEventListener('click', changePosition);
<button class="direction">Perpendicularly</button>
In regards to the following statement:
But when I click on the button nothing changes. I think the problem is with the else statement because when I delete this statement all work.
Your event may be firing twice. It could be calling your event listener twice, effectively reverting the change it just made to the text.
Suggested improvement
Magic strings are bad, and I would recommend the use of enumerable values instead.
const Direction = {
PERPENDICULARLY: 'Perpendicularly',
HORIZONTALLY: 'Horizontally'
};
const changePosition = event => {
event.target.textContent =
event.target.textContent === Direction.PERPENDICULARLY
? Direction.HORIZONTALLY
: Direction.PERPENDICULARLY
};
document.querySelector('.direction').addEventListener('click', changePosition);
<button class="direction">Perpendicularly</button>

jquery - selected text keeps being stored outputting duplicated text

I'm currently trying to make a function to highlight text, then insert into a textarea only what's selected. It's working bar one thing: if I keep selecting text, then selecting something else, it will just add it all together and I can't figure out why.
code to get selected text (along with positioning)
// selected text
function getSelected()
{
var return_text = '';
if (window.getSelection)
{
return_text = window.getSelection();
}
else if (document.getSelection)
{
return_text = document.getSelection();
}
return return_text;
}
Then the code to show a box to insert that text into a textarea, making sure it only allows text from within a comment area...
var quote_box = $('#selective-quote');
$(document).on('mouseup', ".comment-body div", function(e)
{
if ($('#comment').length) // only do this if comment box exists (logged in)
{
var selection = getSelected();
var selectedText = selection.toString();
if (typeof selection !== undefined && selectedText.length > 0 && selection.anchorNode.nodeName == '#text')
{
var container = $(this);
var r=selection.getRangeAt(0).getBoundingClientRect();
var relative=document.body.parentNode.getBoundingClientRect();
// show the quote button box
quote_box.css('position','absolute');
quote_box.css('top',r.bottom -relative.top - 45);
quote_box.css('left',r.left);
quote_box.css('height', 'auto');
quote_box.show();
var text_to_insert = '';
$(document).on('click', "#insert-selective-quote", function(e)
{
var username = container.parent().parent().children('.comment-meta').find('.username').text();
text_to_insert = '[quote='+username+']' + $.trim(selectedText) + '[/quote]';
console.log(text_to_insert);
var current_text = $('#comment').val();
$('#comment').val(current_text + text_to_insert);
quote_box.hide();
});
}
else
{
quote_box.hide();
}
}
});
So if I had text with "this comment here" and I repeatedly highlighted "here" say 4 times (clicking off it each time), it would store it 4 times...I'm so confused. So I click the insert button and then it inserts it 4 times. Why?
It's supposed to only insert what's highlighted there and then, nothing else. Not anything previously highlighted like it seems to do now.
Every time the mouse button is released, you create a new click listener, since the creation of the click listener happens inside of the mouseup handler:
$(document).on('mouseup', ".comment-body div", function(e) {
/* ... */
$(document).on('click', "#insert-selective-quote", function(e) {
/* ... */
})
/* ... */
})
So, at the first mouseup event, the first click listener is installed. On the second mouseup event, the first click listener still exists (since it's never removed) and a second listener is installed as well, and so on.
So after 4 times, you already have 3 click listeners installed from before and install a 4th one. And on clicking the button, all the 4 listeners fire, since they all listen on the same event.
You should either install one listener globally, or remove the existing listener before installing a new one. You can remove any existing click listener using $(document).off('click', '#insert-selective-quote'), just add that before you do the $(document).on('click', '#insert-selective-quote', ...).

JS Always getting the same event object "e" parameter with mousedown

I'm trying to handle a middle mouse button click event with JQuery on a DataTable (https://datatables.net/). Here is my code.
var tbl = document.getElementById("entries");
$(tbl).on('mousedown', function (e) {
e.preventDefault();
if (e.which == 2) {
var table = window.table_entries;
var data = table.dataTable.row($(e.detail)).data();
window.open("/plugin/Changes/#Model.Revision/" + data.BuildId, '_blank');
}
});
I'm always getting the same BuildId (284), no matter where I click. How can I get the correct row?
I also have another code snippet, which works perfectly fine
tbl.addEventListener("cdt.click", function (e) {
var table = window.table_entries;
var data = table.dataTable.row($(e.detail)).data();
window.open("/plugin/Changes/#Model.Revision/" + data.BuildId, '_blank');
window.location("/plugin/Changes/#Model.Revision/" + data.BuildId);
});
Thanks in advance!
if you want to check de middle button click with jquery check this code
$("#foo").on('click', function(e) {
if( e.which == 2 ) {
e.preventDefault();
alert("middle button");
}
});
From this question Triggering onclick event using middle click
And if you want to check downmouse you can check this other #KyleMit answer
Detect middle button click (scroll button) with jQuery
#Jordi Jordi (because I can't comment right now) : Based on JQuery's documentation, click & mousedown both works.
$('h1').on('mousedown', function(e) {
alert(e.which);
});
Will display 1 for LClick, 2 for Middle, 3 for RClick. But this isn't the question.
If you're getting the same BuildId, it's because your selector isn't the good one.
If you're searching to get an exact row, you should change your selector like this :
$('td').on('mousedown', function (e) {
e.preventDefault();
if (e.which == 2) {
// Here you should get the row like this :
var row = $(this).parent();
}
});
Now it's your job to do what you want with this. The var "row" will contain the TR, meaning the row you just give a click.
EDIT : Note that your second code snippet doesn't include e.preventDefault(). Maybe it's the reason this second one works ?

Problem with event.target in IE

I'm writing js for a status update system to be used on various pages throughout a app that I'm working. I am really just starting to get more comfortable with javascript so it has been somewhat of a challenge to get to the point where I have everything now.
The status system is basically a facebook clone. For the most part everything is supposed to function the way that facebook's status updates and status comments do. The intended behavior is that when the user clicks in the status textarea, the div under the status textarea slides out revealing the submit button as well as some other checkboxes.
If the user clicks anywhere else on the page except a link or any element that has the class prevent_slideup the div slides up hiding the submit button and any checkboxes.
I'm using a document.body click function to determine what the user clicked on so I know which form elements to hide if I should even hide them. I do not want this slideup to take place on a textarea if that textarea has focus or the user is selecting a checkbox that goes with that form. Hence the prevent_slideup class. I also do not want to bother running the slideup logic if the user has clicked on a link. I'd prefer they just leave the page without having to wait for the animation.
The code that I was using to accomplish this task can be found in the $(document.body).click(function (e) section below where I'm doing a .is('a') check on the event target.
This code works as expected in chrome and firefox, however in ie when a link is clicked for the first time it seems that the element stored in var target is actually a div instead of an anchor. What ends up happening is that the submit div slides up and the user is not taken to the link that they just clicked on. If a link is clicked a second time the user is taken to the page as you would expect.
It seems to me that there's some kind of a lag in ie as to what the current event being fired is.
The entire status module is working other than this one strange ie bug regarding the users click on the link not being carried out the first time that they click a link after opening the status textarea. Does anything jump out in this script that would explain this behavior or does anyone have any other advice?
Thanks in advance for your help.
$(document).ready(function(){
$("textarea.autoresize").autoResize();
});
$(document.body).click(function (e){
var target = e.target || e.srcElement;
console.log(target);
console.log($(target).is('a'));
if($(target).hasClass('prevent_slideup') || $(target).is('a'))
{
return true;
}
else
{
var active_element = document.activeElement;
var active_status_id = $(active_element).attr('data-status_id');
var active_has_data_status_id = (typeof active_status_id !== 'undefined' && active_status_id !== false) ? true : false;
$('textarea').each(function(){
if($(this).hasClass('status_comment_textarea'))
{
var status_id = $(this).attr('data-status_id');
if($('#comment_textarea_'+status_id).val() === '' && (!active_has_data_status_id || active_status_id !== status_id))
{
hide_status_comment_submit(status_id);
}
}
else if($(this).attr('id') === 'status_textarea')
{
if($('#status_textarea').val() === '' && $(active_element).attr('id') !== 'status_textarea')
{
$('#status_textarea').html($("#status_textarea").attr('placeholder'));
hide_status_submit();
}
}
});
return true;
}
});
$("#status_textarea").live('click', function(){
if($('#status_textarea').val() === $("#status_textarea").attr('placeholder'))
{
$('#status_textarea').html('');
}
show_status_submit();
return false;
});
$(".comment_toggle").live('click', function(){
var status_id = $(this).attr('data-status_id');
show_status_comment_submit(status_id);
return false;
});
$(".status_comment_submit").live('click', function(){
var status_id = $(this).attr('data-status_id');
$('#status_comment_submit_wrapper_'+status_id).addClass('status_comment_submit_successful');
return false;
});
$(".show_hidden_comments").live('click', function(){
var status_id = $(this).attr('data-status_id');
$('#status_hidden_comments_'+status_id).show();
$(this).hide();
return false;
});
function hide_status_submit()
{
$("#status_textarea").removeAttr('style');
$("#status_textarea").blur();
$("#status_block").removeClass('padding_b10');
$("#status_submit_wrapper").slideUp("fast");
return false;
}
function show_status_submit()
{
if ($("#status_submit_wrapper").is(":hidden"))
{
$("#status_block").addClass('padding_b10');
$("#status_submit_wrapper").slideDown('fast');
}
return false;
}
function hide_status_comment_submit(status_id)
{
if(!$('#status_comment_submit_wrapper_'+status_id).is(":hidden"))
{
$('#status_comment_submit_wrapper_'+status_id).hide();
$('#fake_comment_input_'+status_id).show();
$('#comment_textarea_'+status_id).removeAttr('style');
}
return false;
}
function show_status_comment_submit(status_id)
{
if($('#status_comment_submit_wrapper_'+status_id).is(":hidden"))
{
$('#fake_comment_input_'+status_id).hide();
$('#status_comment_submit_wrapper_'+status_id).show();
$('#comment_textarea_'+status_id).focus();
}
return false;
}
function status_comment_submit_successful()
{
hide_status_comment_submit($('.status_comment_submit_successful').attr('data-status_id'));
$('.status_comment_submit_successful').removeClass('status_comment_submit_successful');
return false;
}
I figured out that there were two main issues with my script...
1.) The document.body function and the #status_textarea live click funtioins were conflicting with each other.
2.) After adding the logic for the #status_textarea function into the document.body function I noticed that the script still didn't quite work as expected in internet explorer unless I had an alert in the function. The problem at this point was that the autoresize plugin that I'm using on the textarea was also conflicting with the document.body function.
I was able to rectify the situation by adding a dummy text input and hiding the status textarea. On click of the dummy text input the status textarea is shown and the the dummy text input is hidden. I have no idea why this worked, but it seems to have solved my problems.

:not isn't working

I've created a simple navigation bar that when you click on an item, another opens under it. to disappear the opened I wrote:
$("#container:not(#navbar)").click(function(){
$("#mini_navbar_home").hide()
});
I wanted to say "wherever on the screen (except the navigation bar) that someone clicked, disappear the #mini_navbar_home", but clicking wherever on the container hides that
it's part of the script if helps:
var navs = new Array("#mini_navbar_home","#mini_navbar_aboutus","#mini_navbar_folan");
var colors = new Array("#home_t","#aboutus_t","#folan_t");
$(document).ready(function(){
$("#home_t").click(function(){
change_bg("#home_t")
navbar_slide_toggle("#mini_navbar_home")
});
.
.
.
$("#container:not(#navbar)").click(function(){
hide_all()
change_bg()
});
});
function change_bg(div){
for(i=0; i<colors.length; i++){
if (colors[i] != div){
$(colors[i]).css("backgroundColor", "#8895B7");
}
}
if ($(div).css("backgroundColor") == "rgb(169, 181, 212)"){
$(div).css("backgroundColor", "#8895B7")
}
else {
$(div).css("backgroundColor", "#A9B5D4")
}
}
function navbar_slide_toggle(div){
for(i=0; i<navs.length; i++){
if (navs[i] != div){
$(navs[i]).hide();
}
}
$(div).slideToggle(0);
}
function hide_all(){
for(i=0; i<navs.length; i++){
$(navs[i]).hide()
}
}
by the way, #navabr is nested with #container
i guess my solution will look silly to most of the users :D
I think you're saying that you want to hide #mini_navbar_home when a click happens on #container that is not inside #navbar. This is fairly simple:
$('#container').click(function(e){
var $navbar = $('#navbar');
if (($navbar[0] !== e.target) && // if the click wasn't on navbar itself
!$navbar.has(e.target).length // and it wasn't inside navbar
) {
$("#mini_navbar_home").hide() // hide it
}
});
The advantage this has over stopPropagation is that this allows you to keep using event bubbling on elements within #navbar. stopPropagation would break, for instance, $('a').live(...) calls.
The easier way is going to be to capture clicks on the document, and then preventing bubbling on your nav bar. That way, the click event will never reach the document, and your hide function is never triggered. You can extend the list of "blacklisted" elements later, as well, and this solution still works even if you click on an element inside of your mini nav bar.
var $mini_navbar_home = $("#mini_navbar_home");
$(document).click(function() { $mini_navbar_home.hide() });
$("#navbar").click(function(e) {
e.stopPropagation();
return false;
});

Categories