How to Disable a Browser or Element Scrollbar, But Still Allow Scrolling With Wheel or Arrow Keys

Hide scrollbar while still being able to scroll with mouse/keyboard

For future reference there is also a solution without jQuery - just have the wrapper div style contain overflow:hidden and use this JavaScript two-liner:

// get the width of the textarea minus scrollbar
var textareaWidth = document.getElementById("textarea").scrollWidth;

// width of our wrapper equals width of the inner part of the textarea
document.getElementById("wrapper").style.width = textareaWidth + "px";

See demo or complete HOWTO.

Update: you can use the same principle to create scrollable div without scrollbar: demo.

Remove HTML scrollbars but allow mousewheel scrolling

There are Javascript methods, see the thread you duplicated.

A better solution is to set the target div to overflow:scroll, and wrap it inside a second element that is 8px narrower, who's overflow:hidden.

The target element will have a hidden scrollbar. The mousewheel will work, but the scroll bar will not show.

<div style='overflow:hidden; width:200px;'>
<div style='overflow:scroll; width:208px'>
My mousewheel scrollable content here....
</div>
</div>

Note that 8px as the width of the scrollbar is a random number - it's probably a lot more, and it could require per browser CSS.

Still better than JS in my book.

Remove scrollbar but not scrolling functionality

There is a library for jQuery named jscrollpane http://jscrollpane.kelvinluck.com/#examples that can modify very much.

But if you only want to hide the bar, you can also push this scrollbar out of view: http://jsfiddle.net/H27BK/

<div id="content">
<div id="scrollable"> ... ... ... </div>
</div>

with CSS

#content {
position: relative;
width: 200px;
height: 150px;
border: 1px solid black;
overflow: hidden;
}
#scrollable {
height: 150px;
width: 218px; /* #content.width + 18px */
overflow-y: scroll;
}

This all based up on a bar-width of 18 pixel.


So we can do some javascript scrollbar width detection script or simply add another div that we put in front of the scrollable div.

http://jsfiddle.net/uNzEz/

HTML is now:

<div id="content">
<div id="scrollable">
<div id="txt"> ... ... ...
</div></div></div>

with CSS like:

#content {
position: relative;
width: 200px;
height: 150px;
border: 1px solid black;
overflow: hidden;
}
#scrollable {
height: 150px;
width: 240px; /* the bar-width can be theoretical 240px - 200px = 40px */
overflow-y: scroll;
}
#txt {
width: 200px;
}

Hidding scrollbar but not stoping scrolling

DEMO

MARKUP:

<section>
<article>
<p></p>
<p></p>
</article>
</section>

STYLE:

*{
box-sizing: border-box;
}
section{
width:480px;
height:320px;
overflow:hidden;
margin:0 auto;
border: 2px solid #ccc;
position: relative;
}
article{
height: 100%;
overflow-y: auto;
width: 500px;
padding: 20px 40px 20px 20px;
}

SWING disable or hide scroll bar, but enable wheel?

Based on this answer from CodeRanch, scrolling is disabled when the scroll bars are never shown. You need to override the JScrollBars isVisible property to "trick" into scrolling.

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.Scrollable;

public class Test {

public static void main(String[] args) {
new Test();
}

public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
JScrollPane scrollPane = new JScrollPane(new TestPane());
JScrollBar scrollBar = new JScrollBar(JScrollBar.VERTICAL) {

@Override
public boolean isVisible() {
return true;
}
};
// if appropriate, uncomment
//scrollBar.putClientProperty("JScrollBar.fastWheelScrolling", Boolean.TRUE);
scrollPane.setVerticalScrollBar(scrollBar);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
frame.add(scrollPane);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}

public class TestPane extends JPanel implements Scrollable {

public TestPane() {
}

@Override
public Dimension getPreferredSize() {
return new Dimension(200, 800);
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
FontMetrics fm = g2d.getFontMetrics();
Integer lineY = null;
for (int yPos = fm.getAscent(); yPos < getHeight(); yPos += 30) {
g2d.drawString(Integer.toString(yPos), 10, yPos + fm.getAscent());
if (lineY != null) {
g2d.drawLine(15, lineY, 15, yPos);
}
lineY = yPos + fm.getAscent();
}
}

@Override
public Dimension getPreferredScrollableViewportSize() {
return new Dimension(200, 200);
}

@Override
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
return 64;
}

@Override
public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
return 128;
}

@Override
public boolean getScrollableTracksViewportWidth() {
return false;
}

@Override
public boolean getScrollableTracksViewportHeight() {
return false;
}

}

}

You don't need to use Scrollable, it is used here purely for demonstration purposes to test the theory.

This, however, also stops calling getScrollableUnitIncrement, which may affect the overall speed of the scrolling, something you'll have to investigate further

Oh, there are also other caveats, if one or more components contained in the JScrollPane registers to the MouseWheelListener events, it will stop the scroll pane from been notified

Disable arrow key scrolling in users browser

Summary

Simply prevent the default browser action:

window.addEventListener("keydown", function(e) {
if(["Space","ArrowUp","ArrowDown","ArrowLeft","ArrowRight"].indexOf(e.code) > -1) {
e.preventDefault();
}
}, false);

If you need to support Internet Explorer or other older browsers, use e.keyCode instead of e.code, but keep in mind that keyCode is deprecated and you need to use actual codes instead of strings:

// Deprecated code!
window.addEventListener("keydown", function(e) {
// space and arrow keys
if([32, 37, 38, 39, 40].indexOf(e.keyCode) > -1) {
e.preventDefault();
}
}, false);

Original answer

I used the following function in my own game:

var keys = {};
window.addEventListener("keydown",
function(e){
keys[e.code] = true;
switch(e.code){
case "ArrowUp": case "ArrowDown": case "ArrowLeft": case "ArrowRight":
case "Space": e.preventDefault(); break;
default: break; // do not block other keys
}
},
false);
window.addEventListener('keyup',
function(e){
keys[e.code] = false;
},
false);

The magic happens in e.preventDefault();. This will block the default action of the event, in this case moving the viewpoint of the browser.

If you don't need the current button states you can simply drop keys and just discard the default action on the arrow keys:

var arrow_keys_handler = function(e) {
switch(e.code){
case "ArrowUp": case "ArrowDown": case "ArrowLeft": case "ArrowRight":
case "Space": e.preventDefault(); break;
default: break; // do not block other keys
}
};
window.addEventListener("keydown", arrow_keys_handler, false);

Note that this approach also enables you to remove the event handler later if you need to re-enable arrow key scrolling:

window.removeEventListener("keydown", arrow_keys_handler, false);

References

  • MDN: window.addEventListener
  • MDN: window.removeEventListener
  • MDN: KeyboardEvent.code interface


Related Topics



Leave a reply



Submit