I have a simple pagination script.
When you click the "next" button multiple times in a short period of time, the browser highlights the clickable area. All browsers do this to an element that you click repeatedly.
Is there a way to disable the highlighting of that element?
I feel like I've looked everwhere and cannot find an answer.
Thank You!
Very difficult to do this cross-browser. I usually just assume that IE users are used to stuff looking a little off/wont notice the highlight/etc. I use this snippet which uses jQuery but should be adaptable to pretty much any library:
$.fn.disableSelection = function() {
return $(this).each( function( index, el ) {
if( typeof el.style.MozUserSelect != 'undefined' ) {
el.style.MozUserSelect = 'none';
}
else {
el.onmousedown = function() { return false; }
}
el.style.cursor = 'pointer';
} );
}
Related
In a table, I have a row with two inputs - one select and one text. What I want to achieve is that if one has a value, then the other (on the same row) should disable. This works correctly onload when there is a value in the textbox, but doesn't seem to work when there is a value in only the select box.
As you can see in the example here: http://jsfiddle.net/anAgent/UBUhn/1/ the "change" event works correctly, but it doesn't work onload.
Any help would greatly be appreciated!
I'm working with jQuery 1.5.2 and with both Google Chrome and IE9
Update With Final Code
Thanks #scoopseven and #eicto for your input. Based on these two answers, here's the final code. I hope it helps someone else.
$(document).ready(function() {
$(".validation-compare").change(runRowValidation);
$(".validation-compare").each(runRowValidation);
});
function runRowValidation() {
var $me = $(this),
$other = $('.validation-compare',$me.closest("tr")).not($me),
mVal = $me.val(),
oVal =$other.val();
if(mVal != "" && oVal == "") {
$me.removeAttr('disabled');
$other.attr('disabled',1);
} else if(mVal == "" && oVal != "") {
$other.removeAttr('disabled');
$me.attr('disabled',1);
} else {
$other.removeAttr('disabled');
$me.removeAttr('disabled');
}
}
You can see it in action at: http://jsfiddle.net/anAgent/UBUhn/24/
i don't think that you you need to set the class valid, all you have to do is replacing
var $otherInput = $('.validation-compare', $parent).not('.valid');
by
var $otherInput = $('.validation-compare', $parent).not($me);
And this will resolve your problem on onload. Here is an example
var validme=function() {
var me=$(this);
me.removeClass('validation-compare');
if (me.val()) {
console.log(me);
me.addClass('valid');
me.parent().parent().find('.validation-compare').attr('disabled',1);
me.addClass('validation-compare');
return;
}
me.removeClass('valid');
if (me.parent().parent().find('.validation-compare.valid').length<1) {
me.parent().parent().find('.validation-compare').removeAttr('disabled'); }
me.addClass('validation-compare');
}
$('.validation-compare').each(validme);
$('.validation-compare').change(validme)
http://jsfiddle.net/UBUhn/22/
You need to separate out the function and call it on the click event and on page load. Something like this:
jQuery(function($){
function myFunction() {
// do somestuff
}
// myFunction needs to be called when select is clicked and when page is loaded
$('#someelement').click(myFunction);
$(document).ready(myFunction);
});
Is there a way to set the cursor at the end in a textarea element? I'm using Firefox 3.6 and I don't need it to work in IE or Chrome. It seems all the related answers in here use onfocus() event, which seems to be useless because when user clicks on anywhere within the textarea element Firefox sets cursor position to there. I have a long text to display in a textarea so that it displays the last portion (making it easier to add something at the end).
No frameworks or libraries.
There may be many ways, e.g.
element.focus();
element.setSelectionRange(element.value.length,element.value.length);
http://jsfiddle.net/doktormolle/GSwfW/
selectionStart is enough to set initial cursor point.
element.focus();
element.selectionStart = element.value.length;
It's been a long time since I used javascript without first looking at a jQuery solution...
That being said, your best approach using javascript would be to grab the value currently in the textarea when it comes into focus and set the value of the textarea to the grabbed value. This always works in jQuery as:
$('textarea').focus(function() {
var theVal = $(this).val();
$(this).val(theVal);
});
In plain javascript:
var theArea = document.getElementByName('[textareaname]');
theArea.onFocus = function(){
var theVal = theArea.value;
theArea.value = theVal;
}
I could be wrong. Bit rusty.
var t = /* get textbox element */ ;
t.onfocus = function () {
t.scrollTop = t.scrollHeight;
setTimeout(function(){
t.select();
t.selectionStart = t.selectionEnd;
}, 10);
}
The trick is using the setTimeout to change the text insertion (carat) position after the browser is done handling the focus event; otherwise the position would be set by our script and then immediately set to something else by the browser.
Here is a function for that
function moveCaretToEnd(el) {
if (typeof el.selectionStart == "number") {
el.selectionStart = el.selectionEnd = el.value.length;
} else if (typeof el.createTextRange != "undefined") {
el.focus();
var range = el.createTextRange();
range.collapse(false);
range.select();
}
}
[Demo][Source]
textarea.focus()
textarea.value+=' ';//adds a space at the end, scrolls it into view
(this.jQuery || this.Zepto).fn.focusEnd = function () {
return this.each(function () {
var val = this.value;
this.focus();
this.value = '';
this.value = val;
});
};
#Dr.Molle answer is right. just for enhancement, U can combine with prevent-default.
http://jsfiddle.net/70des6y2/
Sample:
document.getElementById("textarea").addEventListener("mousedown", e => {
e.preventDefault();
moveToEnd(e.target);
});
function moveToEnd(element) {
element.focus();
element.setSelectionRange(element.value.length, element.value.length);
}
So, I have some faux checkboxes (so I could style them) that work with jQuery to act as checked or not checked. There are a number of faux checkboxes in my document, and for each one I have a click function:
var productInterest = [];
productInterest[0] = false;
productInterest[1] = false;
productInterest[2] = false;
// here is one function of the three:
$('#productOne').click(function() {
if (productInterest[0] == false) {
$(this).addClass("checkboxChecked");
productInterest[0] = true;
} else {
$(this).removeClass("checkboxChecked");
productInterest[0] = false;
}
});
The problem seems to be that there is an error in the if statement, because it will check, but not uncheck. In other words it will add the class, but the variable won't change so it still thinks its checked. Anybody have any ideas? Thanks for your help.
UPDATE: So, I need to show you all my code because it works in the way I supplied it (thanks commenters for helping me realize that)... just not in the way its actually being used on my site. so below please find the code in its entirety.
Everything needs to happen in one function, because the UI and data for each checkbox need to be updated at once. So here is the complete function:
$('input[name=silkInterest]').click(function() { // they all have the same name
var silkInterest = [];
silkInterest[0] = false;
silkInterest[1] = false;
silkInterest[2] = false;
if ($(this).is('#silkSilk')) { // function stops working because the .is()
if (silkInterest[0] == false) {
$(this).addClass("checkboxChecked");
silkInterest[0] = true;
} else {
$(this).removeClass("checkboxChecked");
silkInterest[0] = false;
}
alert(silkInterest[0]);
}
if ($(this).is('#silkAlmond')) {
if (silkInterest[1] == false) {
$(this).addClass("checkboxChecked");
silkInterest[1] = true;
} else {
$(this).removeClass("checkboxChecked");
silkInterest[1] = false;
}
}
if ($(this).is('#silkCoconut')) {
if (silkInterest[2] == false) {
$(this).addClass("checkboxChecked");
silkInterest[2] = true;
} else {
$(this).removeClass("checkboxChecked");
silkInterest[2] = false;
}
}
var silkInterestString = silkInterest.toString();
$('input[name=silkInterestAnswer]').val(silkInterestString);
// This last bit puts the code into a hidden field so I can capture it with php.
});
I can't spot the problem in your code, but you can simply use the class you're adding in place of the productInterest array. This lets you condense the code down to a single:
// Condense productOne, productTwo, etc...
$('[id^="product"]').click(function() {
// Condense addClass, removeClass
$(this).toggleClass('checkboxChecked');
});
And to check if one of them is checked:
if ($('#productOne').hasClass('checkboxChecked')) {...}
This'll make sure the UI is always synced to the "data", so if there's other code that's interfering you'll be able to spot it.
Okay, just had a palm to forehead moment. In regards to my revised code- the variables get reset everytime I click. That was the problem. Duh.
i have a strange problem only in Chrome using an iframe but working in all others common browser.
the problem: If i type in the IFRAME and then press the button to send, it work fine, the focus back to the IFRAME and the cursor BLINK.
But if i type and then press ENTER to invoke the event handler function, the focus back but the cursor disappear. And then if you go in another window and then back the cursor appear. This happen only in Chrome. I did the example page to show the problem in action. Click the link below to see.
UPDATE: I added the code also here below
var editorFrame = 'myEditor'
function addFrame() {
var newFrame = new Element('iframe', {
width: '520',
height: '100',
id: editorFrame,
name: editorFrame,
src: 'blank.asp',
class: 'myClass'
});
$('myArea').appendChild(newFrame);
window.iframeLoaded = function() {
// this is call-back from the iframe to be sure that is loaded, so can safety attach the event handler
var iframeDoc, UNDEF = "undefined";
if (typeof newFrame.contentDocument != UNDEF) {
iframeDoc = newFrame.contentDocument;
} else if (typeof newFrame.contentWindow != UNDEF) {
iframeDoc = newFrame.contentWindow.document;
}
if (typeof iframeDoc.addEventListener != UNDEF) {
iframeDoc.addEventListener('keydown', keyHandler, false);
} else if (typeof iframeDoc.attachEvent != UNDEF) {
iframeDoc.attachEvent('onkeydown', keyHandler);
}
};
}
function resetContent()
{
var myIFrame = $(editorFrame);
if (myIFrame) myIFrame.contentWindow.document.body.innerHTML='';
}
function setEditFocus()
{
var iFrame = document.frames ? document.frames[editorFrame] : $(editorFrame);
var ifWin = iFrame .contentWindow || iFrame;
ifWin.focus();
}
function send()
{
resetContent();
setEditFocus();
}
function keyHandler (evt) {
var myKey=(evt.which || evt.charCode || evt.keyCode)
if (myKey==13) {
if (!evt) var evt = window.event;
evt.returnValue = false;
if (Prototype.Browser.IE) evt.keyCode = 0;
evt.cancelBubble = true;
if (evt.stopPropagation) evt.stopPropagation();
if (evt.preventDefault) evt.preventDefault();
send();
}
}
In the HTML page
<body onload="addFrame()">
<div id="myArea"></div>
<input id="myButton" type="button" value="click me to send [case 1]" onclick="send()">
To make more easy to understand the problem i've create a specific page to reproduce the problem with full example and source included.
You can view here by using Google Chrome:
example of the problem
I really need your help because i tried to solve this problem for many days with no luck. And all the suggestions, tips and workaround are well accepted.
Thanks in advance.
I'm not really sure what the cause of the issue is, as there are times where Chrome will give focus to the element correctly, though most of the time it does not. You shouldn't need to request focus at all, since the focus is not lost when you press the key. If you omit the setEditFocus() call, you should notice that it still works correctly in everything but Chrome, which apparently gets offended that you've removed all of the content in the body.
When you set contenteditable, every browser sets the innerHTML of the iframe document's body element to be something different:
Browser | innerHTML
-----------------------------
Internet Explorer | ''
Opera | '<br>\n'
Firefox | '<br>'
Chrome/Safari | '\n'
If you're not expecting to see that extra stuff when you parse the content later, you might want to remove it upfront in addFrame().
I was able to "fix" the problem by doing the following:
First, update the event handler so we can return false in it and prevent Opera from generating HTML for fun when we call getSelection() later...
function addFrame() {
...
window.iframeloaded = function() {
...
if (typeof iframeDoc.addEventListener != UNDEF) {
iframeDoc.addEventListener('keypress', keyHandler, false);
} else if (typeof iframeDoc.attachEvent != UNDEF) {
iframeDoc.attachEvent('onkeypress', keyHandler);
}
}
}
Edit: Removed original function in favour of the new one included below
Finally, return false from the key press handler to fix the Opera issue mentioned above.
function keyHandler (evt) {
var myKey=(evt.which || evt.charCode || evt.keyCode)
if (myKey==13) {
...
return false;
}
}
I had originally done what syockit suggested, but I found it was doing weird things with the caret size in Chrome, which this method seems to avoid (although Firefox is still a bit off...). If you don't care about that, setting the innerHTML to be non-blank is likely an easier solution.
Also note that you should be using className instead of class in the object you pass to new Element(), since IE seems to consider it a reserved word and says that it's a syntax error.
Edit: After playing around with it, the following function seems to work reliably in IE8/Firefox/Chrome/Safari/Opera for your more advanced test case. Unfortunately, I did have to include Prototype's browser detection to account for Opera, since while everything looks the same as far as the JavaScript is concerned, the actual behaviour requires different code that conflicts with the other browsers, and I wasn't able to find a better way to differentiate between them.
Here's the new function, which focuses on the editable content of the iframe, and makes sure that if there is already content in there, that the caret is moved to the end of that content:
function focusEditableFrame(frame) {
if (!frame)
return;
if (frame.contentWindow)
frame = frame.contentWindow;
if (!Prototype.Browser.Opera) {
frame.focus();
if (frame.getSelection) {
if (frame.document.body.innerHTML == '')
frame.getSelection().extend(frame.document.body, 0);
else
frame.getSelection().collapseToEnd();
} else if (frame.document.body.createTextRange) {
var range = frame.document.body.createTextRange();
range.moveEnd('character', frame.document.body.innerHTML.length);
range.collapse(false);
range.select();
}
} else {
frame.document.body.blur();
frame.document.body.focus();
}
}
Updated setEditFocus() (Not really necessary now, but since you already have it):
function setEditFocus()
{
focusEditableFrame($(editorFrame));
}
You know how I solved this one? In resetContent(), replace '' with ' ':
if (myIFrame) myIFrame.contentWindow.document.body.innerHTML=' ';
If it works, good. Don't ask why though, it might be one of those Webkit glitches with Range object, file a bug if you will.
Just quickly, can you try adding semicolons to the end of the lines inside your send() function? And see if that works.
function send() {
resetContent();
setEditFocus();
}
I have written a game in java script and while it works, it is slow responding to multiple clicks. Below is a very simplified version of the code that I am using to handle clicks and it is still fails to respond to a second click of 2 if you don't wait long enough. Is this something that I need to just accept or is there a faster way to be ready for the next click?
BTW, I attach this function using AddEvent from the quirksmode recoding contest.
var selected = false;
var z = null;
function handleClicks(evt) {
evt = (evt)?evt:((window.event)?window.event:null);
if (selected) {
z.innerHTML = '<div class="rowbox a">a</div>';
selected = false;
} else {
z.innerHTML = '<div class="rowbox selecteda">a</div>';
selected = true;
}
}
The live code may be seen at http://www.omega-link.com/index.php?content=testgame
You could try to only change the classname instead of removing/adding a div to the DOM (which is what the innerHTML property does).
Something like:
var selected = false;
var z = null;
function handleClicks(evt)
{
var tmp;
if(z == null)
return;
evt = (evt)?evt:((window.event)?window.event:null);
tmp = z.firstChild;
while((tmp != null) && (tmp.tagName != 'DIV'))
tmp = tmp.firstChild;
if(tmp != null)
{
if (selected)
{
tmp.className = "rowbox a";
selected = false;
} else
{
tmp.className = "rowbox selecteda";
selected = true;
}
}
}
I think your problem is that the 2nd click is registering as a dblclick event, not as a click event. The change is happening quickly, but the 2nd click is ignored unless you wait. I would suggest changing to either the mousedown or mouseup event.
I believe your problem is the changing of the innerHTML which changes the DOM which is a huge performance problem.
Yeah you may want to compare the performance of innerHTML against document.createElement() or even:
el.style.display = 'block' // turn off display: none.
Profiling your code may be helpful as you A/B various refactorings:
http://www.mozilla.org/performance/jsprofiler.html
http://developer.yahoo.com/yui/profiler/
http://weblogs.asp.net/stevewellens/archive/2009/03/26/ie-8-can-profile-javascript.aspx