Jquery/Css Issue #2: Hover Elements triggering unwanted hovering action - javascript

Long time ago, I made a question with the concept: Jquery/CSS challenge, where I use Jquery to fill in for CSS place and was given the hover function (because I haven't learned that before, and is now very useful!) So I copied the code, edited it to my liking to make my homemade 'navigation' buttons made by the span attribute (i know i can use button, but was curious on how it plays here).
So when I begin to test it, I noticed an odd behavior. After I started my hovering activity on multiple 'same' attributes. My mouse acted weirder when my on hover acts like 'off hover' and when I go away it acted like I was 'on hover'. I even edited to mouse enter and mouse leave from the jQuery library and I still run into the same issue, HELP!
Here is my sample of code used for the jQuery-Css Project:
$(document)
.ready(
function() {
var $span = $("span");
$span
.css(
{
"background-color" : "#eef"
}
)
.hover(
function (){
$(this)
.css(
{
"background-color" : "#ddf"
}
)
;
},
function () {
$(this)
.css(
{
"background-color" : "#eef"
}
)
;
}
)
;
}
)
;
Then the appropriate HTML coding used for this scenario:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Jquery Test Page.</title>
<!--[if lte IE 7]>
<style>
.content {
margin-right: -1px;
} /* this 1px negative margin can be placed on any of the columns in this layout with the same corrective effect. */
ul.nav a {
zoom: 1;
} /* the zoom property gives IE the hasLayout trigger it needs to correct extra whiltespace between the links */
</style>
<![endif]-->
</head>
<body>
<div class="menu">
<span id="a">I am button A</span>
<span id="b">I am button B</span>
<span id="c">I am button C</span>
</div>
</body>
</html>
I do spread my coding out just for easy editing purposes, but I need help with this! Thank you all for making this a good community!

It is not acting weird. That is happening because you have made two functions there in the hover event. The first one is fired when you hover and the second one when you left the button. If you want only the hover event you can make only one function there
$span.css({"background-color" : "#eef"}).hover(function (){
$(this).css({"background-color" : "blue"});
});
And you can use mouseleave function in jquery to understand when the user left the button.
Read this article for better understand
http://www.w3schools.com/jquery/event_hover.asp

Related

Javascript -- wait for user interaction without freezing the browser

I don't speak English very well.
My company has developed a web application for internet explorer that very strenuously uses the function showModalDialog and waits for the result.
We are planning to extend the use of the application to other browsers (Firefox, Chrome), and I need to replace "showModalDialog logic" with a logic that will work well on all browsers.
I originally tried using an ajaxcontroltoolkit modalpopup with an iframe inside.
My problem is that, after I have showed the modalpopup, I cannot wait for the user to close the popup window without freezing the web interface.
function OpenDialog() {
var result = window.showModalDialog("page1.html", "input_parameter", "width:100px; height:100px");
//When the popup went closed
alert("result: " + result);
}
//Override showModalDialog function for compatibility with other browser
function myShowModalDialog(url, pars, options) {
//show a jquery modalpopup or ajaxcontroltoolkit modalpopup with an iframe ....
iframe.src = url;
//I need to wait here until the modal popup closed
//HOW?
//get the value from popup
var res = ???????;
return res;
}
window.showModalDialog = myShowModalDialog;
I cannot change the logic for every page in the webapp.
I searched for a method to override the showModalDialog function and recreate the same logic (wait until the popup is closed and get the result that the popup provides for the caller).
Any ideas? Thanks to all
You've discovered the reason why JavaScript relies heavily on asynchronicity, event handlers, and callback functions.
The best solution would be to restructure your code so that your events trigger on event handlers, using jQuery or somesuch to bind the event handlers to the event. Alternatively, you could always use a function in a timeout loop to check periodically if the modal is closed yet, and execute the continuation of your code when it is. That's pretty hacky though, and I don't recommend it. In general, trying to force asynchronous code to fit a synchronous model gets really messy.
Unless I'm not following you, what you need is a callback when the user closes the dialog, right?
Whatever method is executed when the user closes the dialog, monkey patch it to call your function. (A monkey patch is code that adds functionality to existing code, but keeps the old code also).
So if your close method/function looks like:
myCloseDialog = function(){
// do important closing stuff
}
Then you can monkey patch like so:
myNewCloseDialog = function(){
// do important callback stuff, or call your callback function
myCloseDialog(arguments);
}
By the way, your English is very fine :)
I've created a short demo of my suggestion in the comment:
<!DOCTYPE html>
<html>
<head>
<title>modal overlay</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.overlay
{
background-color: rgba(0, 0, 0, 0.1);
position:absolute;
top:0;
left:0;
width:100%;
height:100%;
z-index: 100;
margin:0;
display:none;
}
.box
{
position:absolute;
top:0;
left:0;
bottom:0;
right:0;
width:400px;
height:300px;
background:white;
margin:auto;
padding:10px;
}
</style>
<!--
prepare a style to show/hide overlay and
prevent lost focus when clicking outside the box
-->
<template id="template1">
<style id="style-modal">
*
{ pointer-events: none;
}
.overlay *
{pointer-events: auto;
}
.overlay
{ display:block!important;
}
</style>
</template>
</head>
<body>
<input id="some-input1" type="text">
<button class="modal-open" type="button">open modal dialog</button>
<div id="overlay1" class="overlay">
<div class="box">
<input id="modal-input1" type="text">
<button type="button" class="modal-close">close</button>
</div>
</div>
<script>
document.addEventListener
( 'DOMContentLoaded',
function(ev)
{
var
template1 = document.getElementById('template1'),
styleModal = template1.content.getElementById('style-modal'),
overlay1 = document.getElementById('overlay1'),
box = overlay1.querySelector('.box'),
head = document.querySelector('head')
;
//TODO: could iterate over querySelectorAll
document.querySelector('button.modal-open').addEventListener
( 'click',
function(ev) { head.appendChild(styleModal); },
false
)
overlay1.querySelector('button.modal-close').addEventListener
( 'click',
function(ev)
{ template1.content.appendChild(styleModal);
document.dispatchEvent(new CustomEvent('closemodal', {detail:{relatedTarget:box}}));
},
false
)
},
false
);
document.addEventListener
( 'closemodal',
function(ev){ alert(ev.detail.relatedTarget.querySelector('input').value); },
false
);
</script>
</body>
</html>
Note that this example makes use of <template> element which isn't implemented by IE yet. You can easily generate the style-element in the script, hold it in a variable and add/remove it to/from the head.
Have a look at my showModalDialog polyfill using a modal element and ECMAScript 6 generators, so it does not need an explicit callback function. Statements after showModalDialog() will run after closing the modal.

Javascript onclick event not working in IE8

I have a button in our app that, when you click it, brings up a pop-up window asking if you are sure you want to proceed. Normally, that code would be in our HTML, but for this particular popup, it must be in Javascript. Anyway, the pop-up works just fine in Firefox, Chrome, and IE9, but it does NOT work in IE8. It is extremely frustrating. Does anyone have any ideas on how to fix this? Here is my code:
function graphicalAppConfirm() {
var graphical = $('#application_graphical').is(':checked');
if (graphical == true) {
$('.default_action').attr('onclick', "return confirm('This setting cannot be undone. Are you sure you wish to continue?')");
}
else {
$('.default_action').removeAttr('onclick');
}
}
I tried using the onmousedown event instead, and that made the popup appear, but then it would not go away.
Try using bind and unbind click. You don't necessarily care about the attributes.
function graphicalAppConfirm() {
var graphical = $('#application_graphical').is(':checked');
if (graphical == true) {
$('.default_action').click(function() { return confirm('This setting cannot be undone. Are you sure you wish to continue?'); });
} else {
$('.default_action').unbind('click');
}
}
If you're using jQuery 1.7+ then on/off is recommended instead of bind/unbind. See the documentation http://api.jquery.com/off/
Update: Here is an example with jQuery 1.8 which you can modify for your own usage. You'll probably want to perform the on/off functions when the checkbox is changed so that is how this example works.
<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-1.8.2.min.js"></script>
</head>
<body>
<button id="theone">Does nothing...</button>
<label for="check"><input id="check" type="checkbox" />Enable Button</label>
<div id="output" style="display:none;">Click registered.</div>
<script>
function callback() {
$("#output").show().fadeOut("slow");
}
$("#check").change(function() {
if (this.checked) {
$("body").on("click", "#theone", callback)
.find("#theone").text("Click Me Enabled!");
} else {
$("body").off("click", "#theone", callback)
.find("#theone").text("Click Me Disabled");
}
});
</script>
</body>
</html>
You can figure out the rest from there. You can test and see it work in IE 8 http://jsbin.com/ojejar/6

Disabling browser status bar text

Background
Modern browsers do away with the classic status bar and instead draw a small tooltip at the bottom of their windows that displays the link target on hover/focus.
An example of this (undesirable, in my case) behavior is illustrated in the following screenshot:
Questions
Is there a portable way to disable these tooltips?
Am I missing any obvious drawbacks to doing this in my particular situation?
Is my attempt (see below) a reasonable way of accomplishing this?
Reasoning
I am working on an intranet web application and would like to disable this behavior for some application-specific actions because quite frankly, https://server/# everywhere looks like an eye-sore and is obtrusive since in some instances my application draws its own status bar in that location.
My Attempt
I'm not a web-developer by trade, so my knowledge is still rather limited in this domain.
Anyway, here's my attempt with jQuery:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Target Tooltip Test</title>
<style>
a, span.a {
color: #F00;
cursor: pointer;
text-decoration: none;
}
a:hover, span.a:hover {
color: #00F;
}
a:focus, span.a:focus {
color: #00F;
outline: 1px dotted;
}
</style>
<script src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script>
$(document).ready(function() {
patch();
});
function patch() {
$('a').each(function() {
var $this = $(this).prop('tabindex', 0);
if($this.prop('href').indexOf('#') == -1 || $this.prop('rel').toLowerCase() == 'external') {
return;
}
var $span = $('<span class="a" tabindex="0"></span>');
$span.prop('data-href', $this.prop('href'));
$span.text($this.text());
$this.replaceWith($span);
});
$('a[rel="external"]').click(function() {
window.open($(this).prop('data-href'));
return false;
});
$('span.a').click(function() {
location.href = $(this).prop('data-href');
}).keypress(function(event) {
if(event.keyCode == 13) {
location.href = $(event.target).prop('data-href');
}
}).focus(function() {
window.status = ''; // IE9 fix.
});
}
</script>
</head>
<body>
<ol>
<li>External Link</li>
<li>Action Foo</li>
<li>Action Bar</li>
<li>Action Baz</li>
<li>Email Support</li>
</ol>
</body>
</html>
patch() replaces all links containing # (i.e., application-specific actions in my case) with a span element, makes all "external" links open in a new tab/window and doesn't seem to break custom protocol handling.
Is there a portable way to disable these tooltips?
Nope, other than workarounds like your example above.
Am I missing any obvious drawbacks to doing this in my particular situation?
You seem to be missing the fact that the whole situation is awkward. Why have links at all if you're going to make them look like buttons? Just use buttons. For that matter, why bother with links if you end up switching them out with spans anyway? Just use spans.
Is my attempt (see below) a reasonable way of accomplishing this?
It's not really reasonable as a general approach, because you're removing those anchor elements from the document, so any attached event listeners, expandos, etc. will be lost. It may work for your specific situation, but a more sane approach would be to not use links in the first place (see above).
If you're still determined to do something like this, at least don't replace the a element. Just get rid of its href attribute and set up an event listener as you did in your example. Now it's no longer a link, so it won't show up in the status bar (but it's still the same element, at least).
<button onclick="window.open('yoururlhere.html','_self')">your link text here</button>
Note that this treats ctrl-clicks as ordinary clicks and disables right-clicking. I don't know about middle clicks.
You could also use "a" and merely replace the href with the onclick as in the code above, but when I tried that my "a:hover" styling stopped working. Apparently an "a" without an href is considered unhoverable, at least in Firefox. So I switched to "button" and "button:hover" styling and all was well.
I understand this solution will be considered bad practice, but in some situations, eg the site I'm making made up mainly of full screen photos, aesthetics trumps principles.
The tooltip provides an indication to the user where a link will take them if clicked. It's part of the standard browser user experience and will be expected by users of your site. Changing this expectation because you don't think it looks nice will probably lead to a poor user experience. Any content shown in that area will be visible as soon as the user stops hovering over a link tag.
I know that any link that doesn't tell me where it is going looks pretty suspicious to me.
try this
$(this).removeAttr("href");
$(this).click(function(){}).mouseover(function(){.........}).etc
This is what I do with jQuery:
//remove status bar notification...
$('a[href]').each(function(){
u = $(this).attr('href');
$(this).removeAttr('href').data('href',u).click(function(){
self.location.href=$(this).data('href');
});
});

Chrome jumping caret bug with removeChild

Can someone please shed some light on this problem in Chrome? The removeChild() function makes the caret jump to the end of the div. Anyone got a workaround?
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
var caretX = 0
function keypress(event){
insertAtCaret('<span id="caretpos"></span>');
var caretpos = document.getElementById('caretpos')
//caretX = getX(caretpos) //finds the X position of the element
removeNode(caretpos)
return(true)
}
//Functions used:
function insertAtCaret(text,replaceContents) {
if(!text){return(false);}
if(replaceContents==null){replaceContents=false;}
if(!replaceContents){//collapse selection:
var sel = document.getSelection()
sel.collapseToStart()
}
return(document.execCommand('insertHTML', false, text))
};
function removeNode(el){
el.parentNode.removeChild(el);
}
</script>
</head>
<body contentEditable="true" onkeypress="return(keypress(event))">
<div>Type some content somewhere here > < and watch what happens in chrome</div>
</body>
</html>
Update:
I'm actually trying to get the pixel location of the user's caret by inserting a dummy element, finding its position and then removing it. That said, the problem is a fundamental one in chrome, manipulating the DOM in this way causes the caret to jump to the end of the element
Exactly what should happen to the caret after calling document.execCommand('insertHTML') is undefined, but I agree that Chrome's behaviour is unhelpful. You could get round it by using the insertNode() method of Range to add your dummy element:
var sel = window.getSelection();
sel.collapseToStart();
var span = document.createElement("span");
var range = sel.getRangeAt(0);
range.insertNode(span);
// Get the position here...
span.parentNode.removeChild(span);
An alternative approach to the whole thing is to use Range's getBoundingClientRect() method in browsers that support it. See my answer here:
Coordinates of selected text in browser page
Finally, I've been writing a module to do this for my Rangy library. It's not quite finisihed but there's a demo here: http://rangy.googlecode.com/svn/trunk/demos/position.html

hide and unhide a div

I am designing a web page in which I got struck at some point.
I am using 3 upload buttons in a div, let the id of the div be "uploadDiv"
I have a right arrow and down arrow images
if I click on the down arrow image, the content of the "uploadDiv" should be displayed
if I click on the right arrow image, the content of the "uploadDiv" should be hidden
The images should be in the same place.
What is the solution?
It sounds like you are talking about a collapsible panel of some form. Depending on what the underlying architecture is of your source code is, Microsoft's Ajax Control Toolkit has a pretty good collapsible panel option.
Another great option out there is to look at jQuery and the jQuery UI components.
http://jqueryui.com/demos/accordion/
http://jqueryui.com/demos/accordion/#collapsible
SAMPLE
<script type="text/javascript">
$(function() {
$("#accordion").accordion({
collapsible: true
});
});
</script>
<div id="accordion">
<h3>File Upload</h3>
<div>
CONTENT HERE
</div>
</div>
The question is vague, but whatever your actual goal you'll achieve the effect by toggling a class on your target divs and letting your CSS implement the effect. This is far superior to changing style directly with JS because it separates the concern of styling to the styling layer, and with an umbrella class this let's you cheaply modify the effect with additional properties at a single point.
Now the CSS that you actually want could be visibility: hidden (if you want the layout flow to be preserved) or display: none (if you want the layout to collapse) or even something exotic like changing the opacity or colours if you want to achieve a greying out effect.
Finally enabling this in JS can be done easily by appending or replacing the content of element.className property but realistically a much improved effect can be had by leveraging a library like jquery or mootools which will offer you most of this work already wrapped into widgets and such niceties as animated fading etc..
Don't fall into the maintenance trap of creating the effect with JS and don't fall into the trap of reinventing the wheel where amazing silver rimmed varieties exist already for free.
<script language=javascript type='text/javascript'>
function hidediv() {
if (document.getElementById) { // DOM3 = IE5, NS6
document.getElementById('uploadDiv').style.visibility = 'hidden';
}
else {
if (document.uploadDiv) { // Netscape 4
document.hideshow.visibility = 'hidden';
}
else { // IE 4
document.all.uploadDiv.style.visibility = 'hidden';
}
}
}
function showdiv() {
if (document.getElementById) { // DOM3 = IE5, NS6
document.getElementById('uploadDiv').style.visibility = 'visible';
}
else {
if (document.layers) { // Netscape 4
document.uploadDiv.visibility = 'visible';
}
else { // IE 4
document.all.uploadDiv.style.visibility = 'visible';
}
}
}
</script>
Above script toggles the style.visibility property of the div. which can be "visible" or "hidden"
<img src="right.png" onclick="hidediv()" />
<img src="down.png" onclick="showdiv()" />
Use the onclick events to call the needed hide or show div
Taken from http://www.webmasterworld.com/forum91/441.htm
By using JQuery you can made it in a easy way.
you can Download Here jquery.js file.
js:
<script src="js/jquery.js"></script>
<script>
$j(document).ready(function(){
$("#hide").click(function(){
$("#uploadDiv").hide(); //hide the div
});
$("#show").click(function(){
$("#uploadDiv").show(); //show the div
});
$("#toggle").click(function(){
$("#uploadDiv").toggle(); //toggle the div
});
});
</script>
html:
<div id="uploadDiv">Some text here !</div>
<div id="hide">Hide</div>
<div id="show">Show</div>
<div id="toggle">toggle</div>
click on particular div to perform desired operation.
Add a class to your css file,
.hidden { display: hidden; }
Add a onclick event to your buttons
The button to hide
... onclick="document.getElementById('UploadDiv').className = '.hidden'" ....
The button to show
... onclick="document.getElementById('UploadDiv').className = '.default'" ....
to hide and show your div using jquery you could do something like:
<head>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script>
$(document).ready(function(){
$("#downArr").click(function () {
$("#uploadDiv").toggle();
$("#downArr").toggle();
$("#upArr").toggle();
});
$("#upArr").click(function () {
$("#uploadDiv").toggle();
$("#downArr").toggle();
$("#upArr").toggle();
});
});
</script>
</head>
<body>
<img id="downArr" src="downArr.jpg">
<img id="upArr" src="upArr.jpg" style="display:none;">
<br>
<div id="uploadDiv" style="display:none;">
content
</div>
</body>
Clicking the image downArr.jpg will make upArr.jpg and the content of uploadDiv visible
Check out more examples of the toggle function at http://docs.jquery.com/Effects/toggle
-Fortes
One of the easiest method to do would be using jquery.

Categories