Anchor hidden by overflow moves into view on focus - javascript

I have a simple scroller (similar to the tag scroller at the top to Google images), which uses jquery/javascript.
<div class="chip-scroller widget">
<a class="chip-scroller_nav chip-scroller_nav--prev">
<span class="md-icon">arrow_back_ios</span>
</a>
<ul>
<li>
<a class="chip-scroller_chip">anchor</a>
</li>
<!-- more items here -->
</ul>
<a class="chip-scroller_nav chip-scroller_nav--next">
<span class="md-icon">arrow_back_ios</span>
</a>
</div>
The UL (list) has overflow-x: hidden set, so depending on the screen width and the number of items in the list, some items will be out of view, either to the left or the right of the visible area.
In the example below, 2 are hidden to the left, 3 are visible and 1 hidden to the right.
(hidden) (hidden) [visible visible visible] (hidden)
The list is positioned using javascript, and in the main navigated using the prev/next navigation buttons at each side.
The issue I have is that any of the items can be focused, whether they are visible or not, and focus means that they're immediately brought into view.
However, the scroller doesn't realise things have changed and it breaks my design. For instance the nav buttons may still show when there is nothing more to scroll in a particular direction.
The first thing I tried was to use e.preventDefault() to try and stop any default browser action, but it still bring the item into view. I'm using the on "focus" to capture the event:
$("body").on("focus", ".chip-scroller_chip", moveFocus);
This seemingly has no effect.
I could tag non-visible anchors with tabindex=-1 but I don't want to stop the focus event happening, just regain control back from the browser.
Any ideas would be great.

What if you would add an if on move focus, assign another class with js to which elements you want to do actions, and with an if check if has a class .hassClass(), then if it does do something, else dont.
Add the class while you create an element. To the class that you dont want to show, add overflow: none, do the wanted thing to the other ones.
Atleast I would oreantate towards this.

Related

How can I 'reset' the browser anchor after expanding a div a second time?

I have an element that expands based on a expandedActive value, and a link that toggles the value. The first time you click the link to expand the element, the page stays put and the content expands below. If I then toggle it off and on again without scrolling, the content expands upwards (or rather, the whole page is pushed up) and the browser seems anchored to the expand toggle. If I scroll any amount in any direction, it will expand below as desired.
How can I force the content to always expand down?
I have tried using a tags with and without href, buttons, and a span. I have tried using anchors and scrolling to them, but it is not the desired behaviour.
Below is the basic vue template.
<span v-if="!expandedActive" v-html="longText.length > charLimit ? longText.slice(0, charLimit) + '...' : longText"></span>
<a v-if="!expandedActive && longText.length > charLimit" #click.prevent="toggleExpandedActive()" href="#">Expand</a>
<span v-if="expandedActive" v-html="longText"></span>
<a v-if="expandedActive" #click.prevent="toggleExpandedActive()" href="#">Collapse</a>

$swipe on child elements conflict with scroll and scroll stops working in AngularJS

I have a parent element to which I applied ng-swipe-right and ng-swipe-left. The swipe functionality works well. One of the element's child element has some content that overflows hence scroll gets automatically applied to it. BUT now, this scroll has stopped working after I had applied the swipe functionality. When I remove the swipe, the scroll works.
Can you please advice, how I can have the parent element to have the swipe functionality but its child element which has overflowing content to also retain its scroll functionality.
NOTE: I've not used any plugin for applying scroll functionality, it automatically takes scroll.
Your case requires both the scroll and swipe event to be available, which I couldn't figure out how to do. Also see this question: Cancel ng-swipe-right on child
If anyone else who doesn't need both events sees this: in my use case the user can either swipe or scroll, depending on whether they tapped a gallery image or not. So I could do the following:
<!-- Fit image to page -->
<div class="gallery-content fit-to-page" ng-if="vm.fitToPage"
ng-swipe-right="vm.showPreviousSlide()" ng-swipe-left="vm.showNextSlide()">
<img ng-src="{{vm.currentSlide.url}}" ng-click="vm.fitToPage = false" />
</div>
<!-- Natural image size -->
<div class="gallery-content natural-size" ng-if="!vm.fitToPage">
<img ng-src="{{vm.currentSlide.url}}" ng-click="vm.fitToPage = true" />
</div>
So using the ng-swipe directives on the element I need swipe for, but not on the one I need to scroll.

Javascript drop down menu widget

I have a menu consisting of an <ul> in a Web CMS.
I want several menu items to have sub-items that are displayed in a dropdown list. These sub-items are <ul>s as well.
This is basically easy to do with a few lines of CSS and Javascript, but I am looking for a ready-made Javascript solution that helps me handle the following:
Deal with screen edge situations: If any part the dropdown menu would be outside the current viewport, place it so that it is completely within the viewport.
This is a bitch to code from scratch.
"Nice to have"s would be:
Centered positioning below the drop-down button
Adding a onclick event to the body so that clicking outside the drop down menu will close it; clean removal of the onclick event afterwards
But those I can do myself if necessary.
A nice, small, unobtrusive widget that magically converts my <ul> would be lovely.
If the solution is based on a framework, it has to be Prototype as that's what I'm using in the CMS.
You can get the offsets of the UL, and check whether those are in a certain distance of the viewport.
// Pseudo code
var ul = document.getElementById("menu");
if(ul.offset.x + ul.width > viewport.width) {
ul.offset.x = viewport.width - ul.width;
}
It's also possible to get the exact position of the dropdown button clicked, and then you should apply basic math in order to position the menu beneath it.

JQuery UI slide effect creates a new line

I want to enable an effect on my web app where a user clicks an "Edit" icon and a text box elegantly slides out horizontally immediately to the right of the icon. Currently it is sliding out, but not very elegantly, because when I click on the icon for some reason a new row is created in the browser below where I clicked (and all content below is bumped down). The text box slides out, and then bizarrely jumps back up to where I originally wanted it to go, and the new row created disappears.
Please note, however, that if I put the textbox on its own line so that it is fully left-justified against the margin, that it works just fine. But I want it to scroll it to the right of the icon.
This behavior is the same for IE8 and Firefox.
Here is the HTML:
<img src="../images/edit.gif" onclick="toggleNotebox()" style="cursor:pointer"/>
<span id="AddText" style="display:none">
<input name="AddNoteText" id="TextBox" onkeypress="return addNote(event);" />
</span>
And here is the relevant Javascript:
function toggleNotebox() {
var options = {};
$('#AddText').toggle('slide', options, 500);
}
Here is the jsbin.com URL to see this behavior in action: http://jsbin.com/alopu/edit
Try putting a float: left on both elements.
http://jsbin.com/uzoqo
edit: for some reason the above works but if you try to edit it it doesn't show my changes to the code. not sure what happened.
Inline elements, which spans and inputs are by default, don't honour explicit widths. So jQuery's either changing the display of the animated element to block, or wrapping it in a block element so that that element can be animated.
That's why Samuel's change works - floated elements honour widths.

Ignore mouse interaction on overlay image

I have a menu bar with hover effects, and now I want to place a transparent image with a circle and a "handdrawn" text over one of the menu items. If I use absolute positioning to place the overlay image above the menu item, the user will not be able to click the button and the hover effect will not work.
Is there any way to somehow disable mouse interaction with this overlay image so that the menu will keep on working just as before even though it's beneath an image?
Edit:
Because the menu was generated with Joomla I could not tweak just one of the menu items. And even if I could, I did not feel a Javascript solution was appropriate. So in the end I "marked" the menu item with an arrow outside the menu-item element. Not as nice as I had wanted it to be, but it worked out okey anyway.
The best solution I've found is with CSS Styling:
#reflection_overlay {
background-image:url(../img/reflection.png);
background-repeat:no-repeat;
width: 195px;
pointer-events:none;
}
pointer-events attribute works pretty good and is simple.
So I did this and it works in Firefox 3.5 on Windows XP. It shows a box with some text, an image overlay, and a transparent div above that intercepts all clicks.
<div id="menuOption" style="border:1px solid black;position:relative;width:100px;height:40px;">
sometext goes here.
<!-- Place image inside of you menu bar link -->
<img id="imgOverlay" src="w3.png" style="z-index:4;position:absolute;top:0px;left:0px;width:100px;height:40px;" \>
<!-- Your link here -->
<a href="javascript:alert('Hello!')" >
<div id="mylinkAction" style="z-index:5;position:absolute;top:0px;left:0px;width:100px;height:40px;">
</div>
</a>
</div>
What I've done:
I've crafted a div and sized it to be what a menu option could be sized to, 100x40px (an arbitrary value, but it helps with illustrating the sample).
The div has an image overlay, and a link overlay. The link contains a div sized to be the same as the 'menuOption' div. This way a user click is captured across the whole box.
You will need to provide your own image when testing. :)
Caveat:
If you expect your menu button to respond to the user interaction (for example, changing color to simulate a button), then you will need extra code attached to the javascript you will invoke on the tag, this extra code could address the 'menuOption' element through the DOM and change it's color.
Also, there is no other way I know of that you can take a click event, and have it register on an element underneath a visible page element. I've tried this as well this summer, and found no other solution but this.
Hope this helps.
PS:
The writeup on events at quirksmode went a long way to help me understand how events behave in browsers.
Give the button a higher z-index property than the hand-drawn image:
<img src="hand_drawn_image.gif" style="z-index: 4">
however, make sure you test it in all major browsers. IE interprets z-index differently from FF.
For somebody to come up with more details, you would have to post more info, a link would be best.
Building on what Pekka Gaiser said, I think the following will work. Taking his example and reworking it:
<a href="#" style="z-index: 5">
<!-- Place image inside of you menu bar link -->
<img src="hand_drawn_image.gif" style="z-index: 4">
<!-- Your link here -->
</a>
Here you should be able to place an event on the underlying a-tag and, unless your image has an event, initiates a capture (!IE browsers) and then kills propagation of the event.
If you need a bit more help, let us know a bit more about the situation.
If the image will be statically positioned, you can capture the click event from the image as it bubbles up, by placing the img tag inside the menu item element.
<div onclick="menuclick()">
<img src="overlay.png" style="position:absolute;" />
</div>

Categories

Resources