I am trying to bring focus to window using jquery. The window is popup initiated through a button click on the parent page. I have some ajax calls going on in the child window, so data is being updated. My issue is that if the user clicks on the parent window and hides the child behind it, i would like to bring that child window back to the forefront if there is a data update.
inside $(document).ready I wire up these events:
$(window).blur(function(){
WindowHasFocus =false;
}).focus(function(){
WindowHasFocus =true;
});
Then, if data is updated, I call this function:
function FocusInput(){
if(!WindowHasFocus){
$(window).focus();
}
}
This works as expected in IE8, but in FireFox(and all other browsers) the Blur event nevers seem to fire if I click the parent window. Any suggestions/ideas on how achieve this?
update:
Total facepalm moment:
In FireFox:
* Tools
* Options…
* Content tab
* Advanced button next to “Enable JavaScript”
* check the box named "Raise or Lower Windows"
Total facepalm moment: In FireFox:
Tools
Options…
Content tab
Advanced button next to “Enable JavaScript”
check the box named "Raise or Lower Windows"
This is turned off by default and must be enabled. And also, i assumed that since it didnt work in Chrome, that Safari would be the same, but you know what they say about "assuming" (it works in Safari, but not Chrome).
If there is not a strong reason for having two separate windows then it would be better use "modal boxes", there are plenty of examples out there and jquery plugins to achieve that. An example of such a plugin:
http://www.84bytes.com/2008/06/02/jquery-modal-dialog-boxes/
You're absolutely correct. In FF, it seems as though it does fire the event, but at that same time, it seems like it doesn't register the element as being focused. Therefore the blur event can never be fired. Not sure I'm even explaining that correctly... The following code says it all.
In this example, the box is hidden by default, but is displayed via the focus event listener. In IE 8, if you click the main window, it still fires blur, but in FF it doesn't:
<html>
<head>
</head>
<body>
<div id="hiddenWin" style="width: 100px; height: 100px; background-color: Black; display: none;"></div>
<script type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js"></script>
<script type="text/javascript">
var something = 12;
something += 4;
$(document).ready(function()
{
$("#hiddenWin").focus(function()
{
$(this).show();
}
).blur(function()
{
$(this).hide();
}
)
$("#hiddenWin").focus();
}
);
</script>
</body>
</html>
For your need, would it be feasible to setup an overlay background? Something that is a fixed position # top:0 and left:0 which takes up the whole screen and has a z-index that is less than your popup. That way, when they click the overlay, it will steal focus and then you can hide everything...? IDK, just a suggestion. I'll keep messing around and see if I can figure it out. Good question. +1
It seems like you shouldn't care to know when your window got blurred. When your data updates, your window is either not in focus, in which case you want to focus it, or it is already in focus, and focusing it again doesn't hurt you any.
Yeah the modal thing is probably the way to go but sometimes you just need to do it the way you want to do it.
I would use plain old JavaScript. Name the window and the bring it into focus.
function showImageWindow(imageURL)
{
var imageWindow = window.open(imageURL,"My_Window","width=1000px,height=1000px,menubar=0,titlebar=0,toolbar=0,location=0,scrollbars=0,status=0");
imageWindow.focus();
}
Related
I have a basic JS flashcard game I made. There are 12 "answer buttons" for a user to choose from.
On mobile, the answer buttons retain the hover effect/focus(?) after being tapped (this does not happen on desktop, any browser). This is very confusing from a user standpoint as it can appear as though the app/flashcard is stuck or not updating.
I'm using Bootstrap 4.1.
Here is my button code, but there's nothing unusual about it:
<button type="button" id="E" class="btn btn-lg btn-info ansBtn" value="E">Answer</button>
I've looked at similar questions (but they were regarding bootstrap 3), which suggested using either an anchor tag instead of the button tag, but that didn't work (with and without the href attr).
I've also tried another suggestion to include this bit of jQuery, but it doesn't seem to work with 4.1 either. I've used button ID, and other classnames, but it has not worked.
$(".btn").mouseup(function(){
$(this).blur();
});
Suggestions? Thanks!
Update
So here is the latest. I've added the below CSS. This give mobile users the experience I want (a "flash" of background-color/border-color change only on click/tap). HOWEVER, now when using my macbook pro and TAPPING with my trackpad, the effect does not occur! It works when I click with the trackpad, but not tap with the track pad. :(
.btn.btn-info {
background-color: #17a2b8
}
.btn-info:not(:disabled):not(.disabled).active,
.btn-info:not(:disabled):not(.disabled):active,
.show > .btn-info.dropdown-toggle {
background-color: #117a8b;
border-color: #10707f;
}
You can always add a .setTimeout() function on the objects .onHover() or .onClick() event. This will allow your flashcard to be flipped/blurred after a certain amount of time. Alternatively, you can simply change the functionality of your application for mobile browsers and make it so you have to click to see the answer. You should also look into the .focus() method and possibly try to change focus to another element on the page. If none of this is working, it is probably some quirk with jQuery. I would suggest trying to selct the element this way:
document.querySelector(".btn").onmouseup = function(){
this.blur();
});
or:
document.querySelector(".btn").onmouseup = function(){
document.body.focus();
});
We have a baffling issue whereby when we try to open a modal dialog box from a parent page it opens with 2 vertical scrollbars next to each other. One controls the modal box, the other one controls the main page behind it.
To have 2 scrollbars is not ideal and have tried to implement a solution for this.
We added some javascript in the dialog box page which would set the style to overflow:hidden when the modal dialog is open.
<script>
function myOnLoad() {
window.parent.$('body').css('overflow', 'hidden');
}
and used....
<body onload="myOnLoad()">
This works and effectively removes the scrollbar in the page behind it (i.e it does what it should) however we also want to set the overflow back to ‘auto’ when the modal dialog is closed…
We have done this by adding this code..
<script type="text/javascript">
// close Modal
$("#close").click(function () {
window.parent.$('body').css('overflow', 'auto');
window.parent.$("iframe").attr('src', '');
window.parent.$(".modalDialog").removeClass('show');
});
However this does not seem to work as the modal dialog closes but the scrollbar is still hidden on the main page.
Can anyone tell me what I might be doing wrong here? I have tried different overflow properties but nothing seems to work
Ok try this, I think your page is reloading on click and thus executing your onload:
$("#close").click(function (e) {
e.preventDefault();
window.parent.$('body').css('overflow', 'auto');
window.parent.$("iframe").attr('src', '');
window.parent.$(".modalDialog").removeClass('show');
});
I think that using window.parent might be the problem since this refers to the parent of the iframe wich is gone. or something like that. just use jquery
you can try by just getting the body directly $("body"), asuming you are getting that click function to fire.
edit: i see this has been mentioned above
Add style to body as
body
{
padding-right:0px !important;
overflow-y:hidden !important;
}
I'm designing an HTML page which has one button. The user clicks the button and a simple jQuery script animates that div away, revealing lower page content. You can see it here.
I've noticed that it looks/works fine the first time, but if I refresh the page with the browser button, it doesn't fully reset. The initial container is only half on the page. If I enter the URL again and load the page, it resets as expected.
NOTE: This only happens if you scroll down a bit after clicking the initial button... which seems weird.
I had no idea that there was any difference between these two operations, but there clearly is. What is the difference and how can I fix this problem from happening?
Here's my jQuery code, in case it's relevant:
$(document).ready(function(){
var faqs = $("#FAQ");
$("#learnmore").click(
function(){
$("#home").animate({top:'-=1066px'},600);
$("#more").animate({top:'-=1066px'}, 600, function() {$("#background").hide();} );
$("body").css('overflow-y', 'scroll');
//$("#home").slideUp();
console.log("jquery loaded");
}
);
});
It happens because it is cached by the browser.
If you styles are regularly modiefied, then as easy fix is to attach a unique id on the end of the reference, like
<link href="style.css?time=168768234928" ..../>
What it does, it makes the browser think it is a new request everytime it loads.
It happens because browser trying to scroll to the same position, what was before page reload. To check it, try press button and don't scroll to bottom of page and then reload page.
Okey, the reason is clear.
Now we need solution. Try this:
#more {display:none}
in your css. And then use
$("#more").show().animate(...
in your $("#learnmore").click() function. I hope this will solve the problem.
Update: After posting on the TinyMCE forum (something I should have done before offering the bounty) the primary issue may be solved, but I'm still very much open to anything regarding the other issues of how to disable the resizable behavior (number 2 and 3 at the end of the post).
I am having trouble saving content with TinyMCE in IE8 (not other versions). In IE, certain elements in the editor have handles in each corner and draggable "borders", and when you focus in to start editing, a striped border may appear:
Problem:
If I submit the form while the thick border is still visible (state 3 in the image), the form will not save the content. I have to click into another area of the editor to make all the borders disappear, and then submit the form.
I'm Using the TinyMCE 3.4.6 jQuery package, I don't get this behavior in other browsers.
Update:
I've narrowed down the cause of the issue quite a bit and found a few things:
The problem occurs with or without the jQuery build, and does not depend on which tinymce plugins are in use.
The thicker "border" only seems to appear when there is a (min-)height/width applied to the element, either declared inline or from external CSS.
Using IETester, I was getting errors that claim 'length' is null or not an object when focus from the active element is lost; i.e. when you click anywhere outside the TinyMCE editor.
I did not see this error in a true IE8 install (something I currently can not access), however: this makes sense somewhat, considering the problem and workaround stated above. I had to hit submit twice and dismiss the warnings to get the form to post in IETester.
These borders and handles will actually extend outside of the editor/iframe:
I created a live bare-bones demo, here is the content of it:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script type="text/javascript" src="tiny_mce/jquery.tinymce.js"></script>
<script type="text/javascript">
$(function() {
$('textarea.tinymce').tinymce({
script_url : 'tiny_mce/tiny_mce.js',
content_css : 'test.css'
});
});
</script>
<form action="" method="post">
<textarea class="tinymce" name="content"><p>Testing</p></textarea>
<button type="submit">Submit</button>
</form>
/* Content of test.css */
p {
min-height: 24px; /* this line makes the handles appear */
background-color: #f00;
color: #fff;
}
How to reproduce:
Open the demo in IE8
Click on the existing paragraph, a small 1px border should appear, and you should be unable to edit the text.
Click on the element again, now the thick border appears and text can be edited.
Type a few characters, then click the submit button. The update will not be sent with the $_POST data. If you were to click another area inside the editor, removing the thick border, the data would be sent normally.
Questions/Issues:
Important: How can I get the form to post the edited text without requiring a workaround from the user?
Update: This seems to be resolved in a recent commit from the TinyMCE lead developer. I still have been unable to test on a real IE8 install, but this worked and silenced the errors in IETester.
Less important: Is there any way to prevent or remove the handles and draggable edges completely? I'm guessing this is a concern with IE's implementation of contentEditable and not so much TinyMCE, and may not even be the cause of the problem.
Extra: How can I prevent these handles from extending outside the editor?
Question 2 is due to the IE implementation of contentEditable, This is a ticket at their connect site requesting to fix it https://connect.microsoft.com/IE/feedback/details/576043/paragraphs-with-haslayout-behave-like-a-block-inside-contenteditable (login required)
I don't know of any solution for Question 3, except to wait for a new IE. In the latest IE10 under windows8 they claim that it's fixed https://connect.microsoft.com/IE/feedback/details/576040/resizing-handles-in-contenteditable-elements-are-placed-over-any-other-element (login required), but their solution is to hide the resizing handles always. Well, there's a solution and it's to avoid using any style while you're editing that forces the internal hasLayout flag for IE
alright this is a weird IE8 bug. I've found a workaround but still the tinymce team should fix this.
I've found out that before submitting the form you could set the content of the textarea to the content of the textarea... Sounds weird but calling the .html() triggers a tinymce event that returns the correct html.
$("button").click(function() {
$("textarea").html($("textarea").html());
});
There is apparently no way you can fix the second issue.
Here is an articles that explains it quite well: You can't remove those unless you remove the property that made them appear.
http://www.satzansatz.de/cssd/onhavinglayout.html
(search for the word "remove")
You can still improve a bit by using this on the container (the element with contenteditable):
function fixIE( editableContainer ) {
editableContainer.onmousedown = function ( e ) {
e = e || event;
( e.target || e.srcElement ).focus( );
};
editableContainer.onresizestart = function ( e ) {
e = e || event;
if ( e.stopPropagation ) {
e.stopPropagation( );
}
e.cancelBubble = true;
if ( e.preventDefault ) {
e.preventDefault( );
}
e.returnValue = false;
return false;
};
}
(Your element doesn't have to be a div)
The onmousedown will allow you to click only once to get to the state where you can write.
The onresizestart will prevent resizing.
if you give it hasLayout, it should work. try zoom:1;
I have various links which all have unique id's that are "pseudo-anchors." I want them to affect the url hash value and the click magic is all handled by some mootools code. However, when I click on the links they scroll to themselves (or to the top in one case). I don't want to scroll anywhere, but also need my javascript to execute and to have the hash value in the url update.
Simulated sample code:
button 1
button 2
Home
So if you were to click on the "button 1" link, the url could be http://example.com/foo.php#button1
Does anyone have any ideas for this? Simply having some javascript return void kills the scrolling but also kills my javascript (though I could probably work around that with an onclick) but more importantly, prevents the hash value in the url to change.
The whole point of an anchor link is to scroll a page to a particular point. So if you don't want that to happen, you need to attach an onclick handler and return false. Even just adding it as an attribute should work:
button 1
A side of effect of the above is that the URL itself won't change, since returning false will cancel the event. So since you want the URL to actually change, you can set the window.location.hash variable to the value that you want (that is the only property of the URL that you can change without the browser forcing a reload). You can probably attach an event handler and call something like window.location.hash = this.id though I'm not sure how mootools handles events.
(Also you need all of the IDs to be unique)
You can use the code below to avoid scrolling:
linktxt
I'm probably missing something, but why not just give them different IDs?
button 1
button 2
Home
Or whatever convention you'd prefer.
Also, preventDefault
$(your-selector).click(function (event) {
event.preventDefault();
//rest of your code here
}
I found the solution. Here I save an old location from calling href
and restore it after scrolling
<script language="JavaScript" type="text/javascript">
<!--
function keepLocation(oldOffset) {
if (window.pageYOffset!= null){
st=oldOffset;
}
if (document.body.scrollWidth!= null){
st=oldOffset;
}
setTimeout('window.scrollTo(0,st)',10);
}
//-->
</script>
and in body of page
<a href="#tab1" onclick="keepLocation(window.pageYOffset);" >Item</a>
Thanks to sitepoint
An easier way would probably be to add it as a GET. That is, http://example.com/foo.php?q=#button1 instead of http://example.com/foo.php#button1
This won't have any effect on how the page is displayed (unless you want it to), and most scripting languages already have tools in place to easily (and safely) read the data.
Well here we are 7 years after this answer was published and I found a different way to make it work: just point the window.location.hash to a non-existent anchor! It doesn't work for <a>s but works perfectly in <div>s.
<div onclick="window.location.hash = '#NonExistentAnchor';">button 1</div>
Worked fine in Chrome 56, Firefox 52 and Edge (IE?) 38. Another good point is that this doesn't produce any console errors or warnings.
Hope it helps somebody besides me.
There is a solution without any JavaScript at all:
I will not jump to the top
Use
button 1
where
function setHash(hash) {
event.preventDefault();
history.pushState(null, null, "#"+hash);
}
event.preventDefault() stops browser from what it normally would do on clicking, and history.pushState adds to the sessions history stack.
For further discussion, see here and here