js小技巧8 带纹理网页滚动条效果

 

<!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>
<title>超酷带纹理网页滚动条效果</title>
<meta http-equiv="imagetoolbar" content="no">
<style type="text/css">
 html {
  overflow: hidden;
 }
 body {
  margin: 0px;
  padding: 0px;
  background: #222;
  position: absolute;
  width: 100%;
  height: 100%;
  pointer: default;
 }
 #screen {
  position: absolute;
  left: 20%;
  height: 40%;
  top: 10%;
  width: 60%;
  overflow: auto;
  background: #000;
  color: #fff;
 }
 #screen2 {
  position: absolute;
  left: 20%;
  height: 30%;
  width: 60%;
  top: 60%;
  overflow: auto;
  background: #111;
  color: #fff;
 }
 .content {
  position:relative;
  font-size: 0.8em;
  font-family: verdana;
  color: #fff;
  padding: 1em;
  height: 100%;
 }
 a {
  text-decoration: none;
  color:#ff8000;
 }
 a:hover {
  text-decoration: none;
  background:#ff8000;
  color:#ffffff;
 }
 a:visited {
  text-decoration: none;
  color:#ff8000;
 }
 a:visited:hover {
  text-decoration: none;
  background:#ff8000;
  color:#ffffff;
 }
 .cds_scrollbar {
  position: absolute;
  background: #555 url(http://www.lanrentuku.com/down/js/images/12476505130.gif);
  right: 0px;
  cursor: pointer;
 }
 .cds_scrollbar_over {
  background: #aaa url(http://www.lanrentuku.com/down/js/images/12476497481.gif);
 }
 .cds_scrollbar_pushed {
  background: #fff url(http://www.lanrentuku.com/down/js/images/12476497480.gif);
 }
 .cds_track {
  position: absolute;
  background: #222 url(http://www.lanrentuku.com/down/js/images/12476497482.gif);
  right: -1px;
  top: 0px;
  height: 100%;
  cursor: pointer;
 }
 .cds_up {
  position: absolute;
  background: #f60 url(http://www.lanrentuku.com/down/js/images/12476497483.gif);
  right: 0px;
  top: 0px;
  cursor: pointer;
 }
 .cds_down {
  position: absolute;
  background: #f60 url(http://www.lanrentuku.com/down/js/images/12476497483.gif);
  right: 0px;
  bottom: 0px;
  cursor: pointer;
 }
</style>

<script type="text/javascript">

var cds = {
 O  : [],
 ok : false,
 ym : 0,
 N  : 0,
 fo : 0,
 sc : 0,
 sp : 0,
 to : 0,
 /* on mouse move */
 m_move : function(e) {
  if (!e) e = window.event;
  /* release drag outside of the window - IE only */
  if (cds.fo.sg && !cds.w3c && !e.button) { cds.m_up(); return; }
  /* vertical mouse position */
  cds.ym = e.screenY;
  /* drag scrollbar */
  if (cds.fo.sg) cds.fo.scrollTop = cds.fo.sZ + (cds.ym - cds.fo.yZ) / cds.fo.r;
 },
 /* on mouse up */
 m_up : function (e) {
  if (!e) e = window.event;
  var tg = (e.target) ? e.target : e.srcElement;
  /* clear and skin scrollbar */
  if (cds.fo) cds.fo.sb.className = (tg.className.indexOf('scrollbar') > 0) ? 'cds_scrollbar cds_scrollbar_over' : 'cds_scrollbar';
  document.onselectstart = '';
  cds.clr();
  cds.fo.sg = false;
 },
 /* clear */
 clr : function () {
  clearTimeout(cds.to);
  cds.sc = 0;
  return false;
 },
 /* refresh all scrollbars */
 refresh : function () {
  for (var i = 0, N = cds.N; i < N; i++) {
   var o = cds.O[i];
   o.v_scroll();
   o.sb.style.width = o.st.style.width = o.su.style.width = o.su.style.height = o.sd.style.width = o.sd.style.height = o.w + 'px';
   o.sb.style.height = Math.ceil(Math.max(o.w * .5, o.r * o.offsetHeight) + 1) + 'px';
  }
 },
 /* arrows scrolling loop */
 a_scroll : function () {
  if (cds.sc != 0) {
   cds.fo.scrollTop += 6 * cds.sc / cds.fo.r;
   cds.to = setTimeout(cds.a_scroll, cds.sp);
   cds.sp = 32;
  }
 },
 /* start arrows scrolling */
 m_down : function (o, s) {
  if (cds.sc == 0) {
   o.dv.sb.className = 'cds_scrollbar cds_scrollbar_pushed';
   cds.fo = o.dv;
   cds.sc = s;
   cds.sp = 400;
   cds.a_scroll();
  }
 },
 /* init script */
 init : function () {
  if (window.oper || (!window.addEventListener && !window.attachEvent)) { this.ok = false; return; }
  /* add events */
  function addEvent (o, e, f) {
   if (window.addEventListener) { o.addEventListener(e, f, false); cds.w3c = true; return true; }
   if (window.attachEvent) return o.attachEvent('on' + e, f);
   return false;
  }
  this.ok = addEvent(window.document, 'mousemove', cds.m_move);
  this.ok = addEvent(window.document, 'mouseup', cds.m_up);
  this.ok = addEvent(window, 'resize', cds.refresh);
  return this.ok;
 },
 /* add skinable scrollbar */
 add : function (id) {
  /* get div */
  var dv = document.getElementById(id);
  /* init script */
  if (!cds.ok) cds.init();
  /* return on error */
  if (!cds.ok || !dv) return false;
  /* append div function */
  function cDiv (c) {
   var o = document.createElement('div');
   o.dv = dv;
   o.className = c;
   dc.appendChild(o);
   return o;
  }
  /* clone the original div to create an empty container */
  var dc = dv.cloneNode(false);
  dc.style.overflow = "hidden";
  /* insert the container into the div's parent */
  dv.parentNode.appendChild(dc);
  /* move the original div into the container */
  dc.appendChild(dv);
  /* modify its positionning to fit into the container */
  dv.style.position = 'absolute';
  dv.style.left = dv.style.top = '0px';
  dv.style.width = dv.style.height = '100%';
  /* push div reference in array */
  cds.O[cds.N++] = dv;
  dv.sg = false;
  /* create and append skinned scrollbar HTML elements to the container, on top of the original div */
  dv.st = cDiv('cds_track');
  dv.sb = cDiv('cds_scrollbar');
  dv.su = cDiv('cds_up');
  dv.sd = cDiv('cds_down');
  /* scrollbar on mouse down */
  dv.sb.onmousedown = function (e) {
   if (!this.dv.sg) {
    if (!e) e = window.event;
    /* save active/scrollable div */
    cds.fo = this.dv;
    /* save vertical mouse and scroll position */
    this.dv.yZ = e.screenY;
    this.dv.sZ = dv.scrollTop;
    this.dv.sg = true;
    /* pushed skin */
    this.className = 'cds_scrollbar cds_scrollbar_pushed';
    document.onselectstart = function () { return false; }
   }
   return false;
  }
  /* track on mouse down */
  dv.st.onmousedown = function (e) {
   if (!e) e = window.event;
   /* save active/scrollable div */
   cds.fo = this.dv;
   /* calculate scrollbar position */
   cds.ym = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
   for (var o = this.dv, y = 0; o != null; o = o.offsetParent) y += o.offsetTop;
   this.dv.scrollTop = (cds.ym - y - (this.dv.r * this.dv.offsetHeight / 2) - this.dv.w) / this.dv.r;
   this.dv.sb.onmousedown(e);
  }
  /* arrows on mouse down */
  dv.su.onmousedown = dv.su.ondblclick = function (e) { cds.m_down(this, -1); return false; }
  dv.sd.onmousedown = dv.sd.ondblclick = function (e) { cds.m_down(this,  1); return false; }
  /* release events */
  dv.su.onmouseout = dv.su.onmouseup = cds.clr;
  dv.sd.onmouseout = dv.sd.onmouseup = cds.clr;
  /* scrollbar on mouse over skin */
  dv.sb.onmouseover = function (e) {
   if (!this.dv.sg) this.className = 'cds_scrollbar cds_scrollbar_over';
   return false;
  }
  /* scrollbar on mouse out (default) skin */
  dv.sb.onmouseout  = function (e) {
   if (!this.dv.sg) this.className = 'cds_scrollbar';
   return false;
  }
  /* scrollbar repositionning */
  dv.v_scroll = function () {
   this.r = (this.offsetHeight - 2 * this.w) / this.scrollHeight;
   this.sb.style.top = Math.floor(this.w + this.scrollTop * this.r) + 'px';
  }
  /* calculate scrollbar width */
  dv.w = dv.offsetWidth - dv.clientWidth + 1;
  /* init scroll */
  dv.v_scroll();
  cds.refresh();
  /* hook on scroll browser's event */
  dv.onscroll = dv.v_scroll;
  return dv;
 }
}

onload = function() {
 /* init scrollbars */
 cds.add('screen');
 cds.add('screen2');
}

</script>
</head>
<body>

<div id="screen">
<div class="content">
<h2>Skinned HTML Scrollbar</h2>

Well, usually I don't comment my work, but this one being a "pure technical demo", and as I had to place some content here, I will make an exception.<br><br>
Once upon the time I stumbled upon the great
<a href=http://www.hesido.com/web.php?page=customscrollbar target="_blank">fleXcroll: Cross Browser Custom ScrollBar script</a> by Hesido.
<br><br>I was very curious to see how this was done and even possible, but looking at the JS code, I couldn't understand a bit of it. Sort of disappointed, I decided to "reinvent the [mouse] wheel" and see what I could do myself.
<br><br>
As always, it was just a "pushing the envelope" kind of exercice, and it might or might not work for you. Please don抰 use this in your production sites as it could divide by zero and blow up destroying the world.
<br><br>

My expectations:
<ul>
 <li>Minimal and plain old JS code
 <li>No CSS hack, no "bugs compliant" features, minimum browsers work-arounds
 <li>No JS mousewheel and keyboard event: just hook to the native OS scrolling mechanism (that's the trick, the actual scrollbars are still there, the script is just painting on top of them)
 <li>Skinned scrollbars 100% CSS positionned, by the browser itself and not by my JS code - no lag on resize (that's the second trick)
 <li>Zero CPU cycle used when idle - no setInterval loop
</ul>
<br>
Findings :
<ul>
 <li>Avoid reading cascaded style sheet from JS (that's a mess)
 <li>Avoid dealing with <a href=http://erik.eae.net/archives/2007/07/27/18.54.15/ target="_blank">computed vs. cascaded</a> browsers inconsistencies (that's another mess)
 <li>Firefox is unable to know whether the left mouse button is pressed or not
 <li>SAFARI will handle JS events outside of its window (and that's great!)
</ul>
<br>
Known issues:
<ul>
 <li>Will manage vertical scrollbars only
 <li>Won't work in Opera (onmouseup event won't fire, drawings/refresh artifacts)
 <li>Firefox won't release the left mouse button outside of the browser windows
</ul>
<br>
Developped using Firefox 2.0 + Firebug 1.0. Tests successfully passed on SAFARI win 3.0, Firefox 3 (latest alpha), IE6 and IE7.
<br><br>
That's all folks,
<br><br>
happy dhteumeuleuing :)
<br><br>
GF Nov 2007
<br><br>
<p>查找更多代码,请访问:<a href=http://www.lanrentuku.com target="_blank">懒人图库</a></p>
<br><br>
</div>
</div>

</body>
</html>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值