這是過年的時候自己寫的js滾動條插件的源碼,做出的效果自己並不滿意,正因為做的並不滿意所以回頭重新鞏固和深入學習js,這個插件有如下幾個不太滿意的地方:
內容的過度效果,可以參閱QQ客戶端最近會話列表裡的滾動條,它的滾動非常的平滑,簡單的說就是缺少動畫過渡效果。
並不算完美的兼容性,在IE6、7下的style仍然有點缺憾。
樣式的不完美,例如鼠標懸浮才顯示滾動條,移除後隱藏這種效果都沒有寫。
內部結構的混亂,需要調整內容結構。
滾動條那個圖片畢竟不是美工,自己切圖切的真是惡心到爆了...囧
總體來說還是可以看的,還是缺少一個動畫。在寫這個插件意識到自己的插件用到了一些比較基礎的函數,於是想到把這些函數應該封裝起來,最近仍然在深入學習js,把手頭上這本書看完就應該著手寫這個基礎函數的插件了,當然,動畫引擎必不可少。話不多說,源碼在此(注意:本插件完整版的是有圖片的,請在文末附件中下載完整的插件):
CSS
代碼如下:
.lf_Scroll, .lf_Scroll li { padding: 0; margin: 0; list-style: none; font: 14px/24px "Helvetica Neue" ,Helvetica,Arial, 'Microsoft Yahei' ,sans-serif; outline: none; }
.lf_Scroll { cursor: pointer; width: 10px; position: absolute; right: 0; top: 0; filter: alpha(opacity=50); -moz-opacity: 0.5; -khtml-opacity: 0.5; opacity: 0.5; }
.lf_ScrollFocus { filter: alpha(opacity=100); -moz-opacity: 1; -khtml-opacity: 1; opacity: 1; }
.lfs_Top, .lfs_Center, .lfs_Bottom { background: url('ScrollBar.gif'); width: 10px; height: 10px; }
.lfs_Top { background-position: 1px 0px; }
.lfs_Center { background-position: center 0; height: 100px; }
.lfs_Bottom { background-position: -22px 0; }
/*Developers config*/
.rollDiv { height: 100%; width: 100%; overflow: hidden; position: relative; }
JavaScript
代碼如下:
/*
* This plugin is defined on the simulation Webpage scroll bar, please insert after binding for DOM events
*
* Comment version: 1.0.0
* Author:linkfly
* Sina:為你聚焦半世紀 | cnblogs:http://www.cnblogs.com/silin6/ | Email:linkFly6@live.com
* date:2014-02-05 02:38:35
*
*
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
*/
(function (window, undefined) {
//配置參數信息
var config = {
auto: true,
height: 'auto',
width: 'auto'
};
var linkFlyScroll = function (dom, options) {
/// <summary>
/// 1: 生成模擬滾動條對象,【請在本對象工作之後再為您指定的對象綁定事件,否則您之前綁定的事件將不會進行工作】
///
1.1 - linkFlyScroll(dom) - 在指定的dom上生成滾動條對象
///
1.2 - linkFlyScroll(dom,options) - 生成滾動條對象,同時提供一系列的參數允許您自定義配置該對象的工作模型
/// </summary>
/// <param name="dom" type="String Or element">
/// 傳入js的dom對象,或者為string類型的該對象ID
/// </param>
/// <param name="options" type="Json">
/// 自定義配置該對象的工作模型,有如下選項:
///
[可選]auto(Boolean):當內容並未達到容器的高度的時候,是否自動隱藏滾動條,默認為true(是)
///
[可選]height(Int Or String):默認單位為px,可以為int和String.值為auto則默認采用css的高度
///
[可選]width(Int Or String):默認單位為px,可以為int和String.值為auto則默認采用css的寬度
/// </param>
/// <returns type="linkFlyScroll" />
if (typeof (dom) === 'string') {
dom = document.getElementById(dom);
}
//沒有指定dom和沒有查找到有效的dom
//linkFlyScroll("")、 linkFlyScroll(null)、linkFlyScroll(undefined)
if (!dom || !dom.nodeType)
return this;
//創建容器對象
var scrollObj = document.createElement('div');
//深度克隆內容對象,並未包含事件,所以需要等到linkFlyScroll對象工作完畢後才可以為該dom對象綁定事件
var cloneObj = dom.cloneNode(true);
scrollObj.className = 'rollDiv';
scrollObj.appendChild(cloneObj);
//替換頁面上當前對象
dom.parentNode.replaceChild(scrollObj, dom);
return new linkFlyScroll.prototype.init(scrollObj, options ? options : {});
};
linkFlyScroll.prototype.init = function (dom, options) {
/// <summary>
/// 1: 本對象才是真正意義上工作的對象,特殊的工作方式是因為可能存在linkFlyScroll的靜態調用和實例化調用
///
1.1 - init(dom,options) - 在指定的dom上生成滾動條對象
/// </summary>
/// <param name="dom" type="element">
/// dom對象
/// </param>
/// <param name="options" type="Json">
/// 自定義配置該對象的工作模型,有如下選項:
///
[可選]auto(Boolean):當內容並未達到容器的高度的時候,是否自動隱藏滾動條,默認為true(是)
///
[可選]height(Int Or String):默認單位為px,可以為int和String.值為auto則默認采用css的高度
///
[可選]width(Int Or String):默認單位為px,可以為int和String.值為auto則默認采用css的寬度
/// </param>
/// <returns type="linkFlyScroll" />
/*
* 本對象包含以下屬性:
* isDrag:是否正在拖拽滾動條
* startTop:(工作中)滾動條開始滾動位置
* endTop:(工作中)滾動條結束滾動位置
* topLimit:滾動條頂部極限位置
* bottomLimit:滾動條底部極限位置
* context:內容Dom
* scrollRadix:滾動基數
* target:容器Dom
*/
//當前this對象,為防止this指針在環境中會經常改變(例如綁定事件的時候),所以將當前對象保存起來
var currScroll = this;
//DOMElement
if (dom.nodeType) {
//保存容器和內容DOM
currScroll.target = dom;
currScroll.context = dom.firstChild;
//合並配置參數
currScroll.options = tool.extend(config, options);
if (currScroll.options.width !== 'auto') {
dom.style.width = tool.convertValue(currScroll.options.width);
}
if (currScroll.options.height !== 'auto') {
dom.style.height = tool.convertValue(currScroll.options.height);
}
//查找到有效的dom
while (currScroll.context.nodeType != 1) {
currScroll.context = currScroll.context.nextSibling;
}
//創建滾動條dom
currScroll.scrollUl = document.createElement('ul');
currScroll.scrollUl.className = 'lf_Scroll';
currScroll.scrollUl.appendChild(tool.setClass('li', 'lfs_Top'));
currScroll.scrollUl.appendChild(tool.setClass('li', 'lfs_Center'));
currScroll.scrollUl.appendChild(tool.setClass('li', 'lfs_Bottom'));
currScroll.context.style.position = 'relative';
//先呈現在頁面上才可以讀取位置數據
dom.appendChild(currScroll.scrollUl);
this.change();
tool.addScrollEvent(currScroll.context, function (e) {
//綁定鼠標滾輪事件,3px滾動單位
if (e.wheel > 0) {//滾輪向上滾動
var currTop = currScroll.endTop -= 3;
currScroll.scrollEvent.call(currScroll, currTop);
} else {//滾輪向下滾動
var currTop = currScroll.endTop += 3;
currScroll.scrollEvent.call(currScroll, currTop);
}
});
//需要處理禁止文字在拖動的時候被選中 TODO
//鼠標點下事件,需要判斷是否是左鍵點擊,目前右鍵也會實現滾動 TODO
tool.addEvent(currScroll.scrollUl, 'mousedown', function (e) {
mouseDown.call(currScroll, e);
});
//追加事件,為了更好的用戶體驗在body上實現監聽
tool.addEvent(document.body, 'mousemove', function (e) {
if (currScroll.isDrag) {
//獲取當前鼠標位置
var position = tool.getMousePos(e);
//當前滾動條top位置
var currTop = (currScroll.endTop + position.y - currScroll.startTop);
//call是為了讓this指針准確的指向本工作對象
currScroll.scrollEvent.call(currScroll, currTop);
}
return false;
});
//追加鼠標釋放事件,為了准確的捕捉到釋放事件在body上監聽
tool.addEvent(document.body, 'mouseup', function () {
mouseUp.call(currScroll, []);
});
var mouseDown = function (e) {
/// <summary>
/// 1: 鼠標按下事件
///
1.1 - mouseDown(e) - 滾動條中鼠標按下滾動條事件
/// </summary>
/// <param name="e" type="Event">
/// Event對象
/// </param>
/// <returns type="linkFlyScroll" />
currScroll.isDrag = true;
//獲取當前鼠標y位置
currScroll.startTop = tool.getMousePos(e).y;
tool.addClass(currScroll.scrollUl, 'lf_ScrollFocus');
return false;
};
var mouseUp = function () {
/// <summary>
/// 1: 鼠標釋放事件
///
1.1 - mouseUp() - 滾動條中鼠標釋放滾動條事件
/// </summary>
/// <returns type="linkFlyScroll" />
currScroll.isDrag = false;
currScroll.endTop = currScroll.scrollUl.style.top ? parseInt(currScroll.scrollUl.style.top) : 0;
tool.removeClass(currScroll.scrollUl, 'lf_ScrollFocus');
return false;
};
currScroll.scrollEvent = function (currTop) {
/// <summary>
/// 1: 滾動事件(核心),傳入需要滾動的坐標即可(滾動條top)
///
1.1 - scrollEvent(currTop) - 核心滾動事件
/// </summary>
/// <param name="currTop" type="Int">
/// 滾動條頂部距離上一層容器的top值
/// </param>
/// <returns type="void" />
if (currTop <= currScroll.topLimit || currTop < 0) {//頂部極限
currTop = currScroll.topLimit;
} else if (currTop >= currScroll.bottomLimit) {//底部極限
currTop = currScroll.bottomLimit;
}
//滾動條偏移效果
currScroll.scrollUl.style.top = currTop + 'px';
var tempTop = parseInt(currScroll.context.style.top ? currScroll.context.style.top : 0);
//debug code
// document.getElementById('postionInfo').innerHTML = 'currTop:' + currTop + ' 滾動基數:' + currScroll.scrollRadix + ' bottomLimit:' + currScroll.bottomLimit + ' endTop:' + currScroll.endTop + ' startTop:' + currScroll.startTop + " Y:" + currTop + " offsetTop:" + currScroll.scrollUl.offsetTop + " compute:" + (currTop * currScroll.scrollRadix * -1) + 'px';
//text code
//內容滾動:當前滾動條top*基數取負數
currScroll.context.style.top = currTop * currScroll.scrollRadix * -1 + 'px';
};
return currScroll;
};
};
linkFlyScroll.prototype.init.prototype.change = function () {
/// <summary>
/// 1: 滾動條內容改變函數
///
1.1 - change() - 本函數代表刷新本滾動條對象的數據,在某些情況下,內容的數據是一直在變化的,可以調用本函數對當前滾動條對象刷新數據
/// </summary>
/// <returns type="linkFlyScroll" />
/*
* linkFlyScroll包含的屬性主要在本函數中初始化或重新定義:
* isDrag:是否正在拖拽滾動條
* startTop:(工作中)滾動條開始滾動位置
* endTop:(工作中)滾動條結束滾動位置
* topLimit:滾動條頂部極限位置
* bottomLimit:滾動條底部極限位置
* context:內容Dom
* scrollRadix:滾動基數
* target:容器Dom
*/
//重置或讀取一系列數據
var currScroll = this;
currScroll.isDrag = false,
currScroll.startTop = 0,
currScroll.endTop = (currScroll.scrollUl.style.top ? parseInt(currScroll.scrollUl.style.top) : 0),
currScroll.topLimit = currScroll.target.scrollTop,
currScroll.bottomLimit = currScroll.target.clientHeight,
currScroll.scrollRadix = 10;
//得出滾動條的高度:內容高度*(容器高度/內容高度=容器占內容百分比)
var scrollPx = currScroll.target.clientHeight * (currScroll.target.clientHeight / currScroll.context.offsetHeight);
//滾動條高度
currScroll.scrollUl.childNodes[1].style.height = scrollPx + 'px';
if (currScroll.context.clientHeight <= currScroll.target.clientHeight && currScroll.options.auto) {
currScroll.scrollUl.style.display = 'none';
} else {
currScroll.scrollUl.style.display = 'block';
//當滾動條顯示,修正最大位置數據
currScroll.bottomLimit -= currScroll.scrollUl.offsetHeight;
}
//設置滾動條滾動基數(滾動條沒滾動1px內容滾動像素):(內容高度-容器高度[因為當前容器已經顯示了一屏])/滾動條top(滾動條空白可滾動高度)
currScroll.scrollRadix = (currScroll.context.offsetHeight - currScroll.target.clientHeight) / currScroll.bottomLimit;
return currScroll;
};
linkFlyScroll.prototype.init.prototype.roll = function (value) {
/// <summary>
/// 1: 滾動條偏移方法
///
1.1 - roll(value) - 滾動條滾動方法
/// </summary>
/// <param name="value" type="Int">
/// 滾動條目標滾動的百分比
/// </param>
/// <returns type="linkFlyScroll" />
var currScroll = this;
if (typeof (value) !== 'number') {
return currScroll;
}
var currTop = (currScroll.bottomLimit - currScroll.topLimit) * value / 100;
currScroll.scrollEvent(currTop);
currScroll.endTop = currTop;
return currScroll;
};
/*
* 工具類
*/
var tool = {
setClass: function (element, className) {
/// <summary>
/// 1: 設置元素節點的class屬性
///
1.1 - setClass(element,className) - 設置元素節點的class屬性,如沒有該節點則創建該節點,並返回修改後的節點對象
/// </summary>
/// <param name="element" type="Element Or String">
/// 傳入String則創建該節點,否則修改該節點
/// </param>
/// <param name="className" type="String">
/// Class Name
/// </param>
/// <returns type="Element" />
if (typeof element === 'string') {
element = document.createElement(element);
}
element.className = className;
return element;
},
hasClass: function (element, className) {
/// <summary>
/// 1: 判斷元素是否有class
///
1.1 - hasClass(element,className) - 判斷元素是否有class,在業務中異常(基本沒有該情況的發生)和有該class返回true,否則返回false
/// </summary>
/// <param name="element" type="Element Or String">
/// 節點對象
/// </param>
/// <param name="className" type="String">
/// Class Name
/// </param>
/// <returns type="Element" />
if (!element || element.nodeType !== 1)//讓異常通過,外面不進行處理
return true;
var elementClassName = element.className;
if (elementClassName.length < 1) {
return false;
}
if (elementClassName == className || elementClassName.match(new RegExp("(^|\\s)" + className + "(\\s|$)"))) {
return true;
}
return false;
},
addClass: function (element, className) {
/// <summary>
/// 1: 為元素【追加】class
///
1.1 - addClass(element,className) - 為元素【追加】class,並返回修改後的class
/// </summary>
/// <param name="element" type="Element Or String">
/// 節點對象
/// </param>
/// <param name="className" type="String">
/// Class Name
/// </param>
/// <returns type="Element" />
if (!tool.hasClass(element, className)) {
if (element.className.length < 1) {
element.className = className;
} else {
element.className += ' ' + className;
}
}
return element;
},
removeClass: function (element, className) {
/// <summary>
/// 1: 為元素移除class
///
1.1 - addClass(element,className) - 為元素移除class,並返回修改後的class
/// </summary>
/// <param name="element" type="Element Or String">
/// 節點對象
/// </param>
/// <param name="className" type="String">
/// Class Name
/// </param>
/// <returns type="Element" />
if (tool.hasClass(element, className)) {
var reg = new RegExp("(^|\\s)" + className + "(\\s|$)");
element.className = element.className.replace(reg, '');
}
return element;
},
css: function (element, key) {
/// <summary>
/// 1: 獲取元素css指定的屬性值
///
1.1 - css(element,className) - 獲取元素css指定的屬性值
/// </summary>
/// <param name="element" type="Element Or String">
/// 節點對象
/// </param>
/// <param name="key" type="String">
/// 要獲取的css屬性
/// </param>
/// <returns type="String" />
return element.currentStyle ? element.currentStyle[key] : document.defaultView.getComputedStyle(element, false)[key];
},
addEvent: function (element, type, fn) {
/// <summary>
/// 1: 為元素追加事件
///
1.1 - css(element, type, fn) - 為元素追加事件,函數中this指向事件源
/// </summary>
/// <param name="element" type="Element Or String">
/// 節點對象
/// </param>
/// <param name="type" type="String">
/// 追加的事件名,不含字符on
/// </param>
/// <param name="fn" type="Function">
/// 事件對象
/// </param>
/// <returns type="void" />
if (element.attachEvent) {
element['e' + type + fn] = fn;
element[type + fn] = function () { element['e' + type + fn](window.event); }
element.attachEvent('on' + type, element[type + fn]);
} else if (element.addEventListener) {
element.addEventListener(type, fn, false);
}
},
// removeEvent: function (element, type, fn) {
// /// <summary>
// /// 1: 為元素刪除事件,本函數並未用到
// ///
1.1 - removeEvent(element, type, fn) - 為元素刪除事件
// /// </summary>
// /// <param name="element" type="Element Or String">
// /// 節點對象
// /// </param>
// /// <param name="type" type="String">
// /// 刪除的事件名
// /// </param>
// /// <param name="key" type="String">
// /// 刪除的事件的函數名
// /// </param>
// /// <returns type="void" />
// if (element.detachEvent) {
// element.detachEvent('on' + type, element[type + fn]);
// element[type + fn] = null;
// } else if (element.removeEventListener) {
// element.removeEventListener(type, fn, false);
// }
// },
addScrollEvent: function (element, fn) {
/// <summary>
/// 1: 追加ScrollEvent事件
///
1.1 - addScrollEvent(element,fn) - 在元素上追加ScrollEvent事件(特殊事件,在元素上鼠標滾輪滾動事件)
/// </summary>
/// <param name="element" type="Element Or String">
/// 元素節點
/// </param>
/// <param name="fn" type="Function">
/// 事件方法
/// </param>
/// <returns type="void" />
var bindScrollFn = function (e) {
e = e || window.event;
//判斷滾輪滾動方向:Firefox和其他浏覽器不同
e.wheel = (e.wheelDelta ? e.wheelDelta : -e.detail) > 0 ? 1 : -1; // 通過事件判斷鼠標滾輪反向,1是向上,-1是向下
//阻止浏覽器默認行為
if (e.preventDefault) { //ff
e.preventDefault();
} else {
e.returnValue = false; //ie
}
fn.call(element, e);
}
if (document.addEventListener) {
//ff
element.addEventListener('DOMMouseScroll', bindScrollFn, false);
//w3c
element.addEventListener('mousewheel', bindScrollFn, false);
} else//ie
{
element.attachEvent('onmousewheel', bindScrollFn);
}
},
getEvent: function () {
/// <summary>
/// 1: 獲取Event對象
///
1.1 - getEvent() - 在無參數的情況下獲取Event對象,同時兼容性處理IE和FF
/// </summary>
/// <returns type="Event" />
if (document.all) {
return window.event;
}
func = getEvent.caller;
while (func != null) {
var arg0 = func.arguments[0];
if (arg0) {
if ((arg0.constructor == Event || arg0.constructor == MouseEvent) || (typeof (arg0) == "object" && arg0.preventDefault && arg0.stopPropagation)) {
return arg0;
}
}
func = func.caller;
}
return null;
},
getMousePos: function (ev) {
/// <summary>
/// 1: 獲取當前鼠標坐標
///
1.1 - getMousePos(ev) - 獲取當前鼠標坐標,兼容性處理,返回的對象格式:{ x:鼠標x坐標 , y:鼠標y坐標 }
/// </summary>
/// <param name="ev" type="Event">
/// Event事件對象
/// </param>
/// <returns type="Json" />
if (!ev) {
ev = currScroll.getEvent();
}
if (ev.pageX || ev.pageY) {
return {
x: ev.pageX,
y: ev.pageY
};
}
if (document.documentElement && document.documentElement.scrollTop) {
return {
x: ev.clientX + document.documentElement.scrollLeft - document.documentElement.clientLeft,
y: ev.clientY + document.documentElement.scrollTop - document.documentElement.clientTop
};
}
else if (document.body) {
return {
x: ev.clientX + document.body.scrollLeft - document.body.clientLeft,
y: ev.clientY + document.body.scrollTop - document.body.clientTop
};
}
},
extend: function (oldObj, newObj) {
/// <summary>
/// 1: 將兩個對象進行合並
///
1.1 - extend(oldObj,newObj) - 將兩個對象合並,並返回合並後的對象,采用clone的方式實現,所以不會對兩個對象產生任何影響
/// </summary>
/// <param name="oldObj" type="Object">
/// 要合並的對象A,該對象作為基礎對象,將新對象的同名屬性覆蓋到基礎對象中
/// </param>
/// <param name="newObj" type="Object">
/// 要合並的對象B
/// </param>
/// <returns type="Object" />
var tempObj = tool.clone(oldObj);
for (var key in newObj) {
if (newObj.hasOwnProperty(key) && !tempObj.hasOwnProperty(key)) {
tempObj[key] = newObj[key];
}
}
return tempObj;
},
clone: function (obj) {
/// <summary>
/// 1: 克隆一個對象
///
1.1 - clone(obj) - 克隆一個對象,並返回克隆後的新對象,該對象的原型是被克隆的對象
/// </summary>
/// <param name="obj" type="Object">
/// 要克隆的對象
/// </param>
/// <returns type="Object" />
function Clone() { }
Clone.prototype = obj;
var newObj = new Clone();
for (var key in newObj) {
if (typeof newObj[key] == "object") {
newObj[key] = tool.clone(newObj[key]);
}
}
return newObj;
},
convertValue: function (value) {
/// <summary>
/// 1: 將數值轉換為有效的數值
///
1.1 - convertValue(value) - 將Json配置的css數值轉換為有效的數值,請保證value的值不為"auto"
/// </summary>
/// <param name="value" type="Object">
/// 要轉換的數值
/// </param>
/// <returns type="Object" />
var reg = /^\d+$/g;
if (typeof (value) === 'number' || reg.test(value)) {
return value + 'px';
} else
return value;
}
};
//注冊到window下
window.linkFlyScroll = linkFlyScroll;
//注冊到window.so命名空間下
if (!window.so) {
window.so = {};
}
window.so.scroll = window.linkFlyScroll;
})(window);
代碼示例
代碼如下:
<!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>
<link href="linkFlyScroll/linkFlyRollCss.css" rel="stylesheet" type="text/css" />
<script src="linkFlyScroll/linkFlyScroll-1.0.0.js" type="text/javascript"></script>
<script type="text/javascript">
window.onload = function () {
var config = {
auto: true, //當內容並未達到容器的高度的時候,是否自動隱藏滾動條
height: '100', //滾動條對象工作高度(超過該高度則顯示滾動條),auto取對象當前高
width: 'auto'//滾動條對象工作寬度
};
var scrollObj = so.scroll('obj', config);
// scrollObj.change();//當滾動條內容改變後,需要刷新滾動條的顯示,則調用本方法
// scrollObj.roll(value);//把滾動條定位到某一點上,value為相對於滾動條對象的百分比
};
</script>
</head>
<body>
<div id="obj">
<div>
當前,企業管理領域刮起一股新的“時尚風”,一些巨頭企業紛紛為自己“瘦身”,向更智慧和靈動的業務轉型。據了解,甲骨文軟件正越來越多地把客戶的主要維護成本向咨詢顧問和第三方供應商轉移。
“在中國本土,90%的甲骨文公司業務是通過這些合作伙伴開展的。此外,為了進一步確保甲骨文的收入,CEO埃裡森還購買了夏威夷的一個小島。” Craig Guarente說道。
作為全球副總裁,Guarente非常清楚甲骨文的各項戰略。Guarente具有16年的工作經歷,曾在合同管理、軟件許可證管理、軟件審計方面有豐富經驗。2011年離開甲骨文後,加入了Palisade公司,該公司的主要業務是幫助甲骨文客戶提供軟件承包、審計介入和許可證“優化”等業務。
Guarente表示,Palisade公司業務發展非常迅速。作為第三方機構,Palisade幫助客戶贏得了大筆訂單,因為他們更貼近市場,能更准確地理解用戶需求。
一般來說,咨詢公司是幫助客戶梳理他的實際需求及軟件本身能提供什麼價值。Guarente通過實際操作做了詳細闡述。比如“你想建設一個新的數據中心,想要推出一個新的災難恢復計劃,或者你想進入雲端,第三方公司首先會制定一個規劃圖,最後落實,達成用戶最終目標。如果把軟件部署在很多服務器的不同位置上,企業會有丟失軟件的現象。因為企業軟件很少能得到許可證密鑰。但Oracle已經形成習慣,每一個可能功能都可以在軟件環境下下載。Oracle數據庫管理員通過自動負載的存儲庫(AWR)報告就可以診斷數據庫問題,這是常見的事,但需要你有一個Oracle數據庫包的許可。”
近年來,隨著軟件審計浪潮的興起,許多公司正在安裝軟件資產管理工具來確定他們使用什麼軟件,能使用多長時間,一個企業多少人在用。但資深管理分析師Hegedus說到:“沒有任何工具能准確理解企業規則,尤其是甲骨文的產品應用,需要專業的第三方機構來幫助用戶理解軟件規則。”
那麼怎麼才能為甲骨文的軟件應用打補丁呢?甲骨文總裁馬克•赫德(Mark Hurd)上周表示:在企業應用之初要把第三方機構定義為服務支持方,這樣方便企業日後免費獲得補丁修復和其他支持,而不只是購買產品知識產權。另外,企業要有效利用咨詢顧問,在了解企業使用什麼軟件,協議應該包含什麼內容時,支持成本控制的第一步。不要盲目離開軟件供應商,按照自己預測和猜想的流程采購軟件。
</div>
</div>
</body>
</html>
以上就是本文的全部內容了,講解的十分詳細,希望大家能夠喜歡。