I'm writing a script which prevents form clicking, but i can't make it work in IE7 - 8, maby anyone know why it is?
I try to use ev = e || window.event; but nothing good happens.
Please help, and thanks in future.
(function( button ) {
$( document ).click(function( e ) {
ev = e || event;
var clickedEl = ev.srcElement || ev.target;
var parentClass = $( button ).attr( 'class' ).split(' ')[0];
if ( clickedEl !== button && $( clickedEl ).parents( '.' + parentClass ).
length == 0 && !$( clickedEl ).hasClass( parentClass ) ) {
// DO SOMETHING
}
});
})($('.category_select')[0]);
Because you're using jQuery, an event object will be passed to the callback, regardless of the browser. Though it's important to note that you won't be receiving the "pure" event object: it's wrapped in a jQuery object. To get the true event object, do this:
var trueEvent = e.originalEvent;
That should do the trick, mind you: you won't have the jQuery stopPropagation method in IE8, you'll have to correct for that manually by using .returnValue = false and .cancelBubble = true
(function( button )
{
$( document ).click(function( e )
{
var ev = e.originalEvent,//this is all you need to do, plus ev is a variable, declare it as such,
clickedEl = ev.srcElement || ev.target,//separate var declarations by comma
parentClass = $( button ).attr( 'class' ).split(' ')[0];
if ( clickedEl !== button && $( clickedEl ).parents( '.' + parentClass ).length == 0 && !$( clickedEl ).hasClass( parentClass ) )
{
// DO SOMETHING
}
});
})($('.category_select')[0]);
That should workI also had a look at the jQuery reference this is what it says on the jQuery event object
Related
Let me start this off with I'm working with someone else's code and am still relatively new to jquery/javascript. I am also using classie.js from another file. If any of this code can be improved please let me know - I am still learning.
I would post html but it's rather long. If it's an issue let me know and I will try and get a live version of my site up.
I'm trying to toggle a mobile menu with two different open buttons: sticky-open-button and open-button.
It works fine right up until I go to close the menu element if the target is not the menu element or one of its descendants. Then it will ONLY let openbtn open the menu.
Problem Code:
// close the menu element if the target is not the menu element or one of its descendants..
content.addEventListener( 'click', function(ev) {
var target = ev.target;
if( isOpen && target !== ( openbtn || stickyopenbtn ) ) {
toggleMenu();
}
} );
}
All code:
(function() {
var bodyEl = document.body,
content = document.querySelector( '.content-wrap' ),
stickyopenbtn = document.getElementById( 'sticky-open-button' ),
closebtn = document.getElementById( 'close-button' ),
openbtn = document.getElementById( 'open-button' ),
isOpen = false;
function init() {
initEvents();
}
function initEvents() {
openbtn.addEventListener( 'click', toggleMenu );
stickyopenbtn.addEventListener( 'click', toggleMenu );
if( closebtn ) {
closebtn.addEventListener( 'click', toggleMenu );
}
// close the menu element if the target is not the menu element or one of its descendants..
content.addEventListener( 'click', function(ev) {
var target = ev.target;
if( isOpen && target !== ( openbtn || stickyopenbtn ) ) {
toggleMenu();
}
} );
}
function toggleMenu() {
if( isOpen ) {
classie.remove( bodyEl, 'show-menu' );
}
else {
classie.add( bodyEl, 'show-menu' );
}
isOpen = !isOpen;
}
init(); //make onclick talk to menu
})();
Your OR condition is wrong as openbtn || stickyopenbtn will always return openbtn instance so the click of stickyopenbtn won't be evaluated.
content.addEventListener('click', function (ev) {
var target = ev.target;
if (isOpen && (target !== openbtn && target !== stickyopenbtn)) {
toggleMenu();
}
});
PROBLEM:
UPDATE: I have found that its not just with returned data from a post. Literally every if else statement disregards my variables almost entirely.
I have tried to do something extremely simple to verify my statement above.
When the code below is executed, nothing happens. I added consol.log() in before my if statement ( in place of the alert ) to make sure that its getting the data to the DOM and it is.
HTML
<input type='submit' name='Confirm' class='button' value='Confirm' >
<input type='submit' name='Cancel' class='button' value='Cancel' >
JS
$( '.button' ).on( 'click' , function() {
var btnName = $( this ).attr( 'name' ) ;
var cancel = "Cancel" ;
var confirm = "Confirm" ;
alert( btnName + cancel + confirm ) ;
if ( btnName == cancel ) {
//some function here . .
} else if ( btnName == confirm ) {
//some function here . .
}
EDIT If I run the code below, then the alert is always Cancel... What the fudge.
$( '.button' ).on( 'click' , function() {
var btnName = $( '.button' ).attr( 'name' ) ;
if ( btnName == "Cancel" ) {
alert( 'Cancel' ) ;
} else if ( btnName == "Confirm" ) {
alert( 'Confirm' ) ;
}
Not matter what i click, the functions in the if statement don't run. The weird part is, when it hits alert( btnName + cancel + confirm ) ; The data that is alerted in the browser is accurate, as in, if I click name='Confirm' the alert output looks like ConfirmCancelConfirm...
I assume you have an error:
function( data ) {
if ( returnedData == "Company Added" ) { //right here
$( '#navAdmin' ).click() ;
} else {
alert( data ) ;
}
}
It should be
function( data ) {
if ( data == "Company Added" ) {
$( '#navAdmin' ).click() ;
} else {
alert( data ) ;
}
}
I tried your JS code.
if ( btnName != cancel ) {
// This function is normal
} else {
// This function is also work
}
That's work on my machine and browser. and your (if else else if code is also work).
Chrome 44.0.2403.157 (64-bit)
Finally found my problem
I don't know where it's happening, but when I assign a variable, for example;
$( '.button' ).on( 'click' , function() {
var btnName = $( this ).attr( 'name' ) ;
}
For some reason there was a bunch of whiteSpace being added before the string.
Started Working With:
$( '.button' ).on( 'click' , function() {
var btnName = $( this ).attr( 'name' ) ;
var trimmedData = ( btnName ).trim() ;
if ( trimmedData == "Confirm" ) {
alert( "Confirm" ) ;
} else if ( trimmedData == "Cancel" ) {
alert( "Cancel" ) ;
}
I put this into my $.post function and it is working as well. I don't know where the extra space is coming from, any other thoughts are welcome. Please Let me know if I am doing something horribly wrong here..
I want to contruct a jquery selector as a string and pass its value to the selector.
$(document).on( 'keyup', function( e ) {
if( e.keyCode == 9 ) {
//console.log( e.target );
console.log(e.target.id);
var preTabIndex = document.getElementById(e.target.id).tabIndex;
var nextTabIndex = preTabIndex + 1;
console.log(preTabIndex);
console.log(nextTabIndex);
//console.log($('[tabindex=3]')[0].id);
var selector = "[tabindex=" + nextTabIndex + "]";
console.log(selector);
console.log($(selector)[0].Id);
//document.getElementById($("[tabindex=3]")[0].id).focus();
document.getElementById($(selector)[0].id).focus();
}
} );
Can this be done? I couldn't find it on my initial googling.
With this i am getting an undefined when i do
console.log($(selector)[0].Id);
Yes, you can. Make sure you use the . or # to denote the target. For example,
In your HTML:
<p id="header">hello</p>
In your JS:
var my_selector = "#header";
$(my_selector).html('wow');
I am making a minimal JavaScript WYSIWYG control.
I don't want to use document.execCommand because it doesn't allow arbitrary HTML, it's inconsistent across browsers etc.
Here is what I have so far stripped down to minimum working code:
http://jsfiddle.net/2WxQn/1/
<button data-action="strong"><strong>b</strong></button>
<button data-action="em"><em>i</em></button>
<button data-action="u"><u>u</u></button>
<p contenteditable>The quick brown fox jumps over the lazy dog.</p>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script>
$( function(){
$( 'button' ).on( 'click', function(){
var selection = window.getSelection();
var range = selection.getRangeAt( 0 );
var action = $( this ).attr( 'data-action' );
var node = document.createElement( action );
var frag = range.extractContents();
node.appendChild( frag );
range.insertNode( node );
return false;
});
});
</script>
If some of the selection already contains strong tags (or whatever), how do I make it so that clicking the button a second time removes these tags instead of wrapping the selection with a new strong tag?
Writing this question has given me an idea. I will try it now and answer my own question if it works - that way this question is here in case anybody else comes up against this. Otherwise I shall await your assistance with baited breath :)
EDIT: obviously if somebody else posts a working solution, I will accept their answer rather than mine if it is better.
EDIT(2): so my idea didn't pan out. It turns out that something (probably range.insertNode) will magically balance the tags for you. I don't seem to have enough information from selection, range or frag to always know if the selection is inside a given tag. Any ideas?
EDIT : This is not a good solution. It completely breaks down with anything more complex than a single line of simple text. I have worked out and will be posting a better solution soon.
Figured it out.
I build an array containing each text node in the wysiwyg area, and a list of its parent tags.
Then I wrapped the selection in a custom element so it would be easy to remove later, and so as not to conflict with any existing HTML elements, using the x- prefix as recommended.
I then rebuilt the contents of the wysiwyg element from that list, removing the tag for the clicked button from all nodes in the selection if they all already had it, which is how most wywiwyg editors handle it.
http://jsfiddle.net/x7WRZ/
<button data-action="B"><b>b</b></button>
<button data-action="I"><i>i</i></button>
<button data-action="U"><u>u</u></button>
<p contenteditable>The quick brown fox jumps over the lazy dog.</p>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min.js"></script>
<script>
$( function(){
var selectionWrapper = 'X-SELECTION';
function getTextData( element ) {
function getTextNodesIn( root ) {
var textNodes = [];
var parents = [];
function getTextNodes( node ) {
if( node.nodeType === 3 ){
var text = node.textContent;
textNodes.push({
text: text,
parents: parents.slice( 0 )
});
} else {
if( node !== root ){
parents.push( node.tagName );
}
for( var i = 0, len = node.childNodes.length; i < len; ++i ){
getTextNodes( node.childNodes[ i ] );
}
parents.pop();
}
}
getTextNodes( element );
return textNodes;
}
return getTextNodesIn( element );
}
function handleSelection( container, action ) {
var textData = getTextData( container );
container.innerHTML = '';
//if every textNode in the selection has action as a parent, we want
//to remove it from all of them.
var selection = _( textData ).filter( function( data ){
return _( data.parents ).contains( selectionWrapper );
});
var remove = _( selection ).every( function( data ) {
return _( data.parents ).contains( action ) || data.text.trim() === '';
});
_( selection ).each( function( data ){
if( remove ) {
data.parents = _( data.parents ).without( action );
} else {
data.parents.push( action );
}
});
//rebuild each text node
_( textData ).each( function( data ){
//no need to add empty text nodes
if( data.text === '' ) {
return;
}
//remove duplicates of the same parent tag and remove the selection wrapper
var parents = _( data.parents ).chain().uniq().without( selectionWrapper ).value();
var target = container;
_( parents ).each( function( parent ){
var node = document.createElement( parent );
target.appendChild( node );
target = node;
});
var text = document.createTextNode( data.text );
target.appendChild( text );
});
}
$( 'button' ).on( 'click', function(){
var action = $( this ).attr( 'data-action' );
var selection = window.getSelection();
for( var i = 0; i < selection.rangeCount; i++ ){
var range = selection.getRangeAt( i );
var node = document.createElement( selectionWrapper );
node.appendChild( range.extractContents() );
range.insertNode( node );
handleSelection( $( 'p' )[ 0 ], action );
}
return false;
});
});
</script>
I'm writing a Safari 6 extension which adds a few keyboard shortcuts. One of the things I'd like to do is catch when the user presses ⌘+1 ⌘+2, etc. Right now, Safari seems to not fire any event when this happens. Here's a Fiddle: http://jsfiddle.net/Xe9YQ/ to show the code, and here's the JS:
$( 'body' ).bind( 'keypress', function ( event ) {
var modifier = '';
if ( event.metaKey ) {
modifier += 'cmd-';
}
if ( event.ctrlKey ) {
modifier += 'ctrl-';
}
if ( event.altKey ) {
modifier += 'alt-';
}
if ( event.shiftKey ) {
modifier += 'shift-';
}
$( 'body' ).html( modifier + event.keyCode );
});
If you try "⌘+j", "⌘+t", or even "⌘+0" and "⌘+shift+5" you'll see correct output. From this, it seems that it's not a problem of overriding browser shortcuts, and not a problem of using the numerical row.
Is anyone familiar with this problem? Is this a known bug? I'd appreciate any advice.
You have to use the keydown event in combination with preventDefault(), because ⌘ combinations may have bindings already (in Chrome, for example ⌘ + 1 switches to the first tab).
$( 'body' ).bind( 'keydown', function ( event ) {
var modifier = '';
if ( event.metaKey ) {
event.preventDefault();
modifier += 'cmd-';
}
if ( event.ctrlKey ) {
modifier += 'ctrl-';
}
if ( event.altKey ) {
modifier += 'alt-';
}
if ( event.shiftKey ) {
modifier += 'shift-';
}
$( 'body' ).html( modifier + event.keyCode );
});