I have a header with logo, menu and search. When I'm on desktop I have all elements shown in that order, but if my window width is less than 980px, the menu hides (get's a toggle), and the logo is detached from the nav and attached after the logo. If the width is greater the logo is again detached and attached to the old place in the DOM.
$(window).on('resize', function() {
if ($(window).width() < 980) {
$('#search-container').detach().insertAfter('#logo');
} else {
$('#search-container').detach().insertAfter('#main_menu');
}
});
#logo {
display: block;
margin: 10px auto 15px;
text-align: center;
}
#search-container {
display: inline-block;
vertical-align: top;
margin-top: 8px;
background: #fff;
border-radius: 5px;
padding: 1px 10px;
}
#search-container .header_search {
display: inline-block;
line-height: 6px;
}
#search-container input {
border: 0;
background-color: transparent;
font-style: italic;
color: rgb(114, 114, 114);
color: rgba(114, 114, 114, 0.5);
font-size: 14px;
line-height: 25px;
font-weight: 400;
text-align: left;
display: inline-block;
vertical-align: top;
width: auto;
}
#search-container input:active,
#search-container input:focus {
outline: none;
border: 0;
}
#search-container .submit {
display: inline-block;
margin-left: 10px;
cursor: pointer;
z-index: 10;
}
#search-container .submit i {
color: #d3031c;
font-size: 26px;
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div id="logo">Logo</div>
<div class="menu_wrapper">
<nav>
<ul id="main_menu" class="">
<li>Menu1</li>
<li>Menu2</li>
<li>Menu3</li>
</ul>
<div id="search-container" class="search-box-wrapper hide">
<div class="header_search">
<form name="search" id="search" method="get" action="#">
<input name="s" type="text" placeholder="Search" value="Search">
<a class="submit"><i class="fa fa-search"></i></a>
</form>
</div>
</div>
</nav>
</div>
Now the issue happens on mobile phones (and from the feedback, only on Android), when you tap on the input field to enter the search query, resize is being activated, and the search container detaches and attaches itself in the same space. And I have no idea why this happens. When I comment the part of the jquery code with the resize, I can type in the input field without the problem.
Why is resize being triggered on click? I checked the media queries, and I am not expanding the element in any way.
I still have no idea why this happens (the resize), but I found a solution:
I am turning off the window resize on $('#search-container') click event:
$('#search-container').on('click', function(){
$(window).off('resize');
});
Stops the window from resizing (which was causing the issue), and you can type on android with ease now :)
This is happening because the soft keyboard opens when the input element is clicked. Apparently resize triggers on a multitude of events, as described here: https://www.quirksmode.org/dom/events/resize_mobile.html.
Your solution works, but you could also use this approach, i.e.
$(window).on('resize', function(){
// If the current active element is a text input, we can assume the soft keyboard is visible.
if( $(document.activeElement).prop('type') !== 'text') {
if ($(window).width() < 980) {
$('#search-container').detach().insertAfter('#logo');
} else {
$('#search-container').detach().insertAfter('#main_menu');
}
}
}
It took me a while to realize that the mobile keyboard was triggering a resize event. I found out just by commenting out the resize functionality. I have two search inputs on the page and funny enough this problem happens to only one input, the one that I was moving in to a side menu on resize.
So what worked for me was to create a global boolean that would be true if my input was clicked. Then in my resize function i check if my boolean is true and if it is I force focus the input, if it is not then I execute the resize logic.
var isClicked = false;
function resize(){
if(isClicked){
$('#search-input').focus().select();
}else{
//resize logic
}
}
document.addEventListener("DOMContentLoaded", function(event) {
$('#search-input').click(function(){
isClicked = true;
});
resize();
});
On iphones, if the font-size of input-field is less than 16px, the 'ios' auto zooms the page. Set the font-size of input-field to 16px to tackle this problem.
Related
I'm currently developing an e-catalogue. Following the suggestion of a Stackoverflow contributor, I now have a navigation bar with a dropdown that produces a two-container menu. Next, I am trying to set it in such a way that when one hovers over a specific element in one container (the left container), the contents of the other container (the right one) of the dropdown, change and allows the user, interact with the changed contents of the right container.
I am using 'mouseenter' and 'mouseleave' event handlers, and yes, you've guessed it, the moment I leave the element (in the left container) I hovered over to trigger the change (in the right container), the contents of the right container reverse back to their original contents!
To get 'round' this problem, within the mouseenter eventlistener function, I wrote in a second mouseenter eventlistener function, this time for the right container itself. I hoped that if I left the element (in the left container), that triggered the change in the right container, and went into the right container, I would be able to interact with the altered contents of the right container. Alas, it worked it!
The problem now, however, is that ANYTIME I hover over the right container, the contents change as if I had hovered over the specific element in the left container, regardless of whether or not I had actually hovered over that element in the left container.
I have tried numerous approaches, including, 'mouseout' (which 'bubbles'), and also tried giving the two mouseenter event functions, names, so that the 'inner' function for the mouseenter event of the right container only executes when the 'outer' function for the mouseenter event of the element in the left container has executed (a very Pythonistic way of thinking!), but nothing has worked.
I need to keep a mouseout or mouseleave event of some sort for the element in the left container; otherwise, the change in the right container will persist as you move the mouse on to other elements in the left container.
Ultimately, I want each element in the left container to trigger different changes in the contents of the right container, much like what you see in the dropdown here.
A minimal working version of my code is shown below:
// block-1h selectors
const breakingLine = document.querySelector(".breakingline");
const breaking = document.querySelector(".breaking");
// block-2h selector(s)
const block2H = document.querySelector(".block-2h");
const drop2HCaptionText = document.querySelector(".drop-2h-captiontext");
// Event listeners
breakingLine.addEventListener("mouseenter", function() {
drop2HCaptionText.textContent = "Camon C2000 Rotavator";
block2H.addEventListener("mouseenter", function() {
drop2HCaptionText.textContent = "Camon C2000 Rotavator";
})
})
breaking.addEventListener("mouseleave", function() {
drop2HCaptionText.textContent = "Boss Ladderspan 3T Scaffold Tower (Single Width)";
block2H.addEventListener("mouseleave", function() {
drop2HCaptionText.textContent = "Boss Ladderspan 3T Scaffold Tower (Single Width)";
})
})
.nav-list {
list-style: none;
border: 1px solid blue;
display: flex;
flex-flow: row wrap;
align-items: left;
justify-content: left;
color: white;
background-color: #429CD9;
}
#hire-dropdown {
position: absolute;
cursor: pointer;
padding-right: 3em;
padding-left: 3em;
}
.hdrop,
.block-1h,
.block-2h {
display: none;
}
#hire-dropdown:hover * {
display: grid;
}
#hire-dropdown .hdrop {
grid-template-areas: "block-1h block-2h";
grid-template-columns: 1fr 1fr;
}
.block-1h {
grid-area: "block-1h";
height: 30em;
}
.block-2h {
grid-area: "block-2h";
background-color: white;
border: 1px solid black;
height: 40em;
}
.drop-1h-list {
list-style: none;
display: block;
border: 1px solid black;
background-color: white;
height: 40em;
}
.drop-most-popular-hire,
.drop-2h-captiontext {
color: #3D3F41;
}
.drop-most-popular-hire {
padding-left: 3em;
}
<nav>
<ul class="nav-list">
<li>Nothing</li>
<li class="to-hire">
<div id="hire-dropdown">To Hire
<div class="hdrop">
<div class="block-1h">
<ul class="drop-1h-list">
<li>Access</li>
<li class="breakingline"><a class="breaking" href="#">Breaking</a></li>
<li class="compactionline"><a class="compaction" href="#">Compaction</a></li>
</ul>
</div>
<div class="block-2h">
<h3 class="drop-most-popular-hire">Our most popular product in this category</h3>
<p class="drop-2h-captiontext">Boss Ladderspan 3T Scaffold Tower (Single Width)</p>
</div>
</div>
</div>
</li>
</ul>
</nav>
Your (constructive) help will be most appreciated.
You could just remove the mouseleave event listener.
When you enter a li element in the left container, the mouseenter event listener will be fired and the text in the right container will be changed.
The content will be changed to another text only when you enter another element in the left container.
const drop2HCaptionText = document.querySelector(".drop-2h-captiontext");
let texts = [
"Boss Ladderspan 3T Scaffold Tower (Single Width)",
"Camon C2000 Rotavator",
"Boss Ladderspan 3T Scaffold Tower (Single Width)",
]
let listItems = document.querySelectorAll('.drop-1h-list li');
listItems.forEach((item, index) => {
item.addEventListener('mouseenter', () => {
drop2HCaptionText.textContent = texts[index];
})
})
.nav-list {
list-style: none;
border: 1px solid blue;
display: flex;
flex-flow: row wrap;
align-items: left;
justify-content: left;
color: white;
background-color: #429CD9;
}
#hire-dropdown {
position: absolute;
cursor: pointer;
padding-right: 3em;
padding-left: 3em;
}
.hdrop,
.block-1h,
.block-2h {
display: none;
}
#hire-dropdown:hover * {
display: grid;
}
#hire-dropdown .hdrop {
grid-template-areas: "block-1h block-2h";
grid-template-columns: 1fr 1fr;
}
.block-1h {
grid-area: "block-1h";
height: 30em;
}
.block-2h {
grid-area: "block-2h";
background-color: white;
border: 1px solid black;
height: 40em;
}
.drop-1h-list {
list-style: none;
display: block;
border: 1px solid black;
background-color: white;
height: 40em;
}
.drop-most-popular-hire,
.drop-2h-captiontext {
color: #3D3F41;
}
.drop-most-popular-hire {
padding-left: 3em;
}
<nav>
<ul class="nav-list">
<li>Nothing</li>
<li class="to-hire">
<div id="hire-dropdown">To Hire
<div class="hdrop">
<div class="block-1h">
<ul class="drop-1h-list">
<li>Access</li>
<li class="breakingline"><a class="breaking" href="#">Breaking</a></li>
<li class="compactionline"><a class="compaction" href="#">Compaction</a></li>
</ul>
</div>
<div class="block-2h">
<h3 class="drop-most-popular-hire">Our most popular product in this category</h3>
<p class="drop-2h-captiontext">Boss Ladderspan 3T Scaffold Tower (Single Width)</p>
</div>
</div>
</div>
</li>
</ul>
</nav>
I have a div "wtb_wrapper_middle" in middle of my web page.
For that div only scroll able in web page. In left and right div are not movable, it fixed in my web page.
So I want to mouse always focus on that particular div wherever my mouse clicked or mouse hover. Means when i use keyboard up or down button at that time that particular div only should be scroll.
Is there possible in JQuery.
My code is like below.
<div id="wtb_wrapper_inner">
<div id="wrapper_left">
....
....
....
</div>
<div id="wtb_wrapper_middle">
....
....
....
....
</div>
<div id="wtb_wrapper_right">
....
....
....
</div>
</div>
In from above html code "wtb_wrapper_middle" area only scrolls in my web page.
I have tried the below
window.onload = function() {
document.getElementById("wtb_wrapper_middle_inner").focus();
};
In this code is focus only on page load, but if clicked mouse in somewhere else, at that time also that middle area should be scroll. That is not working.
My Ajax callback function like below
$.ajax({
type: "POST",
url: "search.php?ajaxrequest=yes",
data: query_string
}).done(function( data ) {
$(".wtb_p_loader").remove();
$("#wtb_wm_listing").append(data);
});
I'm appending return success data into the di wtb_wm_listing which is i have placed inside of main div wtb_wrapper_middle
Anyone help me to make it success..
You can do this using css position: fixed;
The two outer divs are fixed to the screen regardless of scroll position. Then the central div scrolls regardless of where the mouse pointer is. You can use top and bottom to fix the full height of the screen, then left and right to fix each on either side.
You can still interact with content in the fixed outer divs.
And the Html is
<div class='left'>
<a href='#'>Hover to check the mouse focus and scorll</a>
</div>
<div class='center'>
//some long content
</div>
<div class='right'>
</div>
Css for doing this action.
a {
color: #000;
display: block;
font-family: arial;
margin: 10px;
text-decoration: none;
}
a:hover {
background-color: #f03055;
color: #fafafa;
}
p {
color: #fafafa;
font-family: arial;
line-height: 24px;
margin: 0 0 25px 0;
padding: 0 2%;
}
.center {
background-color: #97c;
height: 2000px;
margin: 0 25%;
width: 50%%;
}
.left {
background-color: #7c9;
bottom: 0;
left: 0;
position: fixed;
top: 0;
width: 25%;
}
.right {
background-color: #7c9;
bottom: 0;
position: fixed;
right: 0;
top: 0;
width: 25%;
}
EDIT: to filter out input elements
document.body.onkeydown = function(event){
var e = event || window.event,
target = e.target || e.srcElement;
if (target.tagName.toUpperCase() == 'INPUT') return;
document.getElementById("wtb_wrapper_middle_inner").focus();
};
this will move focus to your middle div whenever keydown event occurs.
I am looking for a way to have a div appear after the user clicks a hyperlink, and then have that same div disappear when the user clicks it again. Currently, the user is only able to have the div appear when the hyperlink is pressed, but when you click the hyperlink again, the div remains in it's "display: block;" state. Here is what I mean:
HTML
<a onclick="showDiv()" id="ShowAboutButton">What's This?</a>
<div id="About">
</div>
CSS
#ShowAboutButton {
text-align: center;
margin-top: 40px;
background-color: white;
border: none;
cursor: pointer;
font-family: "Lato Light";
font-size: 22px;
}
#About {
width: 900px;
height: 600px;
margin-left: auto;
margin-right: auto;
margin-top: 10px;
background-color: gray;
display: none;
transition: height 2s;
}
Javascript
function showDiv() {
document.getElementById('About').style.display = "block";
}
If it is at all possible, can someone please show me how to give the user the ability to click the hyperlink and have the div slide in with a transition effect, and then when the hyperlink is clicked again have it slide back out with a transition effect? Any help would be much appreciated! Thank you in advance!
You can do this very easily with jquery slideToggle:
$("#ShowAboutButton").click(function(){
$("#About").slideToggle();
});
JSFIDDLE
$('#ShowAboutButton').click(function() {
$('#About').toggle();
});
Vanilla JavaScript :
var about = document.getElementById('About');
about.style.display='none';
document.getElementById('ShowAboutButton').addEventListener('click', function() {
//Toggling
if(about.style.display != 'block') {
return about.style.display='block';
}
about.style.display = 'none';
});
OOPS. Missed top of your code.
<a onclick="showDiv(document.getElementById('About'))" id="ShowAboutButton">What's This?
<div id="About">
</div>
function showDiv(obj) {
if(obj.style.display == "block"){
obj.style.display='none'
}
else(obj.style.display == "none"){
obj.style.display='block'
}
}
I've been stuck trying to figure out how to code a menu much like what you see on the Playstation website: http://us.playstation.com/
EDIT: Fiddle: http://jsfiddle.net/jjcarlson/7q64A/
So far I have a number of issues. The first is that I have been unable to create the 100% width, because, I am assuming, of the parent/child relationship.
The second issue I have is that my Timeout works on all class elements rather than only the currently hovered element. In other words, if all elements have slid down and one is hovered over, they all will remain open until none of them have been hovered for 1.5 seconds. I admit that my inability to come up with a solution may be due to my limited experience with the language. Below is the CSS:
.accordion-container {
width: 90%;
padding-bottom: 5px;
margin: 20px 0 0 20px;
}
.accordion {
width: 40%;
padding: 20px;
margin: 0 15px 35px;
position: relative;
float: left;
display: inline-block;
}
.accordion-question {
margin: 0;
padding: 0 0 5px 20px;
display: inline-block;
color: #06F;
background-color: #9F0;
cursor: pointer;
}
.accordion-answer-container {
padding: 0 20px;
overflow: hidden;
color: #999;
background: #F00;
}
.accordion-answer {
margin: 0;
padding: 0;
color: #0C0;
}
Then, the JQuery:
$(document).ready(function () {
var menu = $('.accordion-answer')
var timeout = 0;
var hovering = false;
menu.hide();
$('.accordion-question').hover(function () {
hovering = true;
// Open the menu
$(this).closest('.accordion').find('.accordion-answer')
.stop(true, true)
.delay(400).slideDown(600);
if (timeout > 0) {
clearTimeout(timeout);
}
})
.on("mouseleave", function () {
resetHover();
});
$('.accordion-answer').hover(function () {
hovering = true;
startTimeout();
})
.on("mouseleave", function () {
resetHover();
});
function startTimeout() {
timeout = setTimeout(function () {
closeMenu();
}, 1500);
};
function closeMenu() {
if (!hovering) {
$('.accordion-answer').stop(true, true).slideUp(400);
}
};
function resetHover() {
hovering = false;
startTimeout();
};
});
And finally, the HTML:
<div class="accordion-container">
<div class="accordion">
<div class="accordion-question">
<h2>Is this a question?</h2>
</div>
<div class="accordion-answer-container">
<div class="accordion-answer">
<p>To be honest, I am not sure</p>
<ul>
<li>List item one</li>
<li>List item two</li>
</ul>
<p>That is all.</p>
</div>
</div>
</div><!-- /accordion -->
<div class="accordion" id="testanchor">
<div class="accordion-question">
<h2>What would be a good second question?</h2>
</div>
<div class="accordion-answer-container">
<div class="accordion-answer">
<p>I don’t know, man!</p>
<p>That is all.</p>
</div>
</div>
</div><!-- /accordion -->
</div>
Styling is minimal right now (sorry) as I'm just trying to get this figured out. Thank you for any help you can provide.
To get a width of 100% you should not display them as inline-block and set the width of .accordion to 100%.
In the hover-event you set hovering to true. If the next hover-event occurs prior to the call of closeMenu, then the if clause will already be false.
You should be able to accomplish the 100% width of your dropdown by altering the css of your .according-answer-container to a fixed position along with setting left and right to 0:
.accordion-answer-container {
padding: 0 20px;
overflow: hidden;
color: #999;
background: #F00;
position: fixed;
left: 0;
right: 0;
}
An update to your fiddle shows this working
I have 5 diffrent backgrounds which change from one to another when mouseover menu links like that:
3 different screenshots out of 5
I want that the web site works properly in all browsers, but I get very different results. In firefox, background image dissapears and reappears on each menu link, but only first time when I go over a link with a cursor, other times works fine. In chrome backgrounds disappear and reappear on every onmouseover. And in IE onmouseover doesn't work at all nor the menu.
So I'm asking you to help me fix this, both things, dissapearing and the menu in IE. I found out that this disappearing and reappearing happens because of slow image loading, but I have no idea how to repair my code to fix this.
I just wrote my code in jsFiddle and menu doesn't work in it as well. And I noticed that when I downscale windows into the size smaller than div, the whole thing starts to deform. I thought I already fixed it, but it seems that I don't know how to that as well. You can see my code here:
My Code in jsFiddle
CSS
body
{
background-image:url(Slike/Ozadja/Osnova.png);
background-repeat:no-repeat;
background-position:center;
background-attachment:local;
background-color: #FFFAF0;
background-size:794px;
}
#layoutWidth div
{
width:628px;
margin:auto;
display:table;
overflow:hidden;
}
div .header
{
height:85px;
text-align:center;
display:table-row;
}
div .menu
{
height:173px;
display:table-row;
}
#ddm
{ margin-top: 30px;
padding: 0;
z-index: 30}
#ddm li
{ margin-left:12px;
margin-top:10px;
padding: 0;
list-style: none;
float: left;
font: bold 100% arial}
#ddm li a
{ display: block;
margin: 0 6px 0 0;
padding: 4px 4px;
width: 130px;
background: transperent;
color: #FFF;
text-align: center;
text-decoration: none}
#ddm li a:hover
{ background: transparent;
color: #C0C0C0;
}
#ddm div
{ position: absolute;
visibility: hidden;
margin-top:10px;
padding: 0;
background: transparent;
}
#ddm div a
{ position: static;
display: block;
margin-left: -16px;
padding: 5px 10px;
width: 150px;
white-space: normal;
text-align: center;
text-decoration: none;
background: transperent;
color: #000;
font: bold 11px arial;
}
#ddm div a:hover
{ background: transparent;
color: #696969}
div .body
{
height:650px;
text-align: left;
display:table-row;
}
div .footer
{
display:table-row;
}
HTML
<html>
<head>
<title>Drop-Down Menu</title>
<meta name="keywords" content="">
<meta name="description" content="">
<meta http-equiv="Content-Type"
content="text/html;charset=UTF-16">
<link rel="stylesheet" type="text/css" href="Stil.css">
<!-- dd menu -->
<script type="text/javascript">
<!--
var timeout = 500;
var closetimer = 0;
var ddmenuitem = 0;
var myImage = {};
myImage.m1 = 'Prvi_predal.png';
myImage.m2 = 'Drugi_predal.png';
myImage.m3 = 'Tretji_predal.png';
myImage.m4 = 'Cetrti_predal.png';
function mopen(id)
{
mcancelclosetime();
if(ddmenuitem) ddmenuitem.style.visibility = 'hidden';
ddmenuitem = document.getElementById(id);
ddmenuitem.style.visibility = 'visible';
document.body.style.backgroundImage = 'url(Slike/Ozadja/'+myImage[id]+')';
}
function mclose()
{
if(ddmenuitem) ddmenuitem.style.visibility = 'hidden';
document.body.style.backgroundImage = 'url(Slike/Ozadja/Osnova.png)'
}
function mclosetime()
{
closetimer = window.setTimeout(mclose, timeout);
}
function mcancelclosetime()
{
if(closetimer)
{
window.clearTimeout(closetimer);
closetimer = null;
}
}
document.onclick = mclose;
// -->
</script>
</head>
<body>
<div id="layoutWidth">
<div class="header">
<a href="Domov.html">
<img src="Slike/Logo/Logo.png" alt="Mankajoč logotip" width="279" height="80"></a>
</div>
<div class="menu">
<ul id="ddm">
<li>Obdelava lesa
<div id="m1" class="prvi" onmouseover="mcancelclosetime()" onmouseout="mclosetime()">
Izdelki iz iverala
Izdelki iz masive
Obnova pohištva
</div>
</li>
<li>Talne obloge
<div id="m2" class="drugi" onmouseover="mcancelclosetime()" onmouseout="mclosetime()">
Laminat
Parket
</div>
</li>
<li>Ostale storitve
<div id="m3" class="tretji" onmouseover="mcancelclosetime()" onmouseout="mclosetime()">
Uporaba mavčnih plošč
Lažja zidarska dela
Fotografiranje dogodkov
Video zajem dogodkov
</div>
</li>
<li>Informacije
<div id="m4" class="cetrti" onmouseover="mcancelclosetime()" onmouseout="mclosetime()">
O podjetju
Kontakt
Kje se nahajamo
Galerija
</div>
</li>
</ul>
<div style="clear:both"></div>
<div style="clear:both"></div>
</div>
<div class="body">
<p>Brez pomena.</p>
<br />
<p> Tole tudi! </p>
</div>
<div class="footer">
Brez pomena.
</div>
</div>
</body>
</html>
For blinking background images, and other images which you want to use from JS, you need to preload, or it will be blinking. How to preload an image? Click here
(It's blinking, because when the page was loaded, the image wasn't. So, that image which you want to use, isn't at the user. The browser download it, but until that time, theres no image what it can show for him/her. This is the reason.)
IE is blocking JS in default (like IE 10). You need to enable it. I've got a warning bubble an the bottom, which say, I've blocking everything... or something like that. You can't enable this from script. Only you can create a warning message for the user, which you remove if JS is enabled.
An extra thing, in jsFiddle it will work the page if you select the "no warp - in <head>" option from the second drop down list at top left. After that you need to click run at top.