gpt4 book ai didi

javascript - 如何使此 float 菜单仅在特定#divs 可见时才起作用?

转载 作者:行者123 更新时间:2023-11-28 13:08:18 24 4
gpt4 key购买 nike

我需要做一个 float 菜单,我在网上搜索,在这里找到了一个脚本http://www.jtricks.com/javascript/navigation/floating.html

/* Script by: www.jtricks.com
* Version: 1.12 (20120823)
* Latest version: www.jtricks.com/javascript/navigation/floating.html
*
* License:
* GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html
*/
var floatingMenu =
{
hasInner: typeof(window.innerWidth) == 'number',
hasElement: typeof(document.documentElement) == 'object'
&& typeof(document.documentElement.clientWidth) == 'number'};

var floatingArray =
[
];

floatingMenu.add = function(obj, options)
{
var name;
var menu;

if (typeof(obj) === "string")
name = obj;
else
menu = obj;


if (options == undefined)
{
floatingArray.push(
{
id: name,
menu: menu,

targetLeft: 0,
targetTop: 0,

distance: .07,
snap: true,
updateParentHeight: false
});
}
else
{
floatingArray.push(
{
id: name,
menu: menu,

targetLeft: options.targetLeft,
targetRight: options.targetRight,
targetTop: options.targetTop,
targetBottom: options.targetBottom,

centerX: options.centerX,
centerY: options.centerY,

prohibitXMovement: options.prohibitXMovement,
prohibitYMovement: options.prohibitYMovement,

distance: options.distance != undefined ? options.distance : .07,
snap: options.snap,
ignoreParentDimensions: options.ignoreParentDimensions,
updateParentHeight:
options.updateParentHeight == undefined
? false
: options.updateParentHeight,

scrollContainer: options.scrollContainer,
scrollContainerId: options.scrollContainerId,

confinementArea: options.confinementArea,

confinementAreaId:
options.confinementArea != undefined
&& options.confinementArea.substring(0, 1) == '#'
? options.confinementArea.substring(1)
: undefined,

confinementAreaClassRegexp:
options.confinementArea != undefined
&& options.confinementArea.substring(0, 1) == '.'
? new RegExp("(^|\\s)" + options.confinementArea.substring(1) + "(\\s|$)")
: undefined
});
}
};

floatingMenu.findSingle = function(item)
{
if (item.id)
item.menu = document.getElementById(item.id);

if (item.scrollContainerId)
item.scrollContainer = document.getElementById(item.scrollContainerId);
};

floatingMenu.move = function (item)
{
if (!item.prohibitXMovement)
{
item.menu.style.left = item.nextX + 'px';
item.menu.style.right = '';
}

if (!item.prohibitYMovement)
{
item.menu.style.top = item.nextY + 'px';
item.menu.style.bottom = '';
}
};

floatingMenu.scrollLeft = function(item)
{
// If floating within scrollable container use it's scrollLeft
if (item.scrollContainer)
return item.scrollContainer.scrollLeft;

var w = window.top;

return this.hasInner
? w.pageXOffset
: this.hasElement
? w.document.documentElement.scrollLeft
: w.document.body.scrollLeft;
};

floatingMenu.scrollTop = function(item)
{
// If floating within scrollable container use it's scrollTop
if (item.scrollContainer)
return item.scrollContainer.scrollTop;

var w = window.top;

return this.hasInner
? w.pageYOffset
: this.hasElement
? w.document.documentElement.scrollTop
: w.document.body.scrollTop;
};

floatingMenu.windowWidth = function()
{
return this.hasElement
? document.documentElement.clientWidth
: document.body.clientWidth;
};

floatingMenu.windowHeight = function()
{
if (floatingMenu.hasElement && floatingMenu.hasInner)
{
// Handle Opera 8 problems
return document.documentElement.clientHeight > window.innerHeight
? window.innerHeight
: document.documentElement.clientHeight
}
else
{
return floatingMenu.hasElement
? document.documentElement.clientHeight
: document.body.clientHeight;
}
};

floatingMenu.documentHeight = function()
{
var innerHeight = this.hasInner
? window.innerHeight
: 0;

var body = document.body,
html = document.documentElement;

return Math.max(
body.scrollHeight,
body.offsetHeight,
html.clientHeight,
html.scrollHeight,
html.offsetHeight,
innerHeight);
};

floatingMenu.documentWidth = function()
{
var innerWidth = this.hasInner
? window.innerWidth
: 0;

var body = document.body,
html = document.documentElement;

return Math.max(
body.scrollWidth,
body.offsetWidth,
html.clientWidth,
html.scrollWidth,
html.offsetWidth,
innerWidth);
};

floatingMenu.calculateCornerX = function(item)
{
var offsetWidth = item.menu.offsetWidth;

var result = this.scrollLeft(item) - item.parentLeft;

if (item.centerX)
{
result += (this.windowWidth() - offsetWidth)/2;
}
else if (item.targetLeft == undefined)
{
result += this.windowWidth() - item.targetRight - offsetWidth;
}
else
{
result += item.targetLeft;
}

if (document.body != item.menu.parentNode
&& result + offsetWidth >= item.confinedWidthReserve)
{
result = item.confinedWidthReserve - offsetWidth;
}

if (result < 0)
result = 0;

return result;
};

floatingMenu.calculateCornerY = function(item)
{
var offsetHeight = item.menu.offsetHeight;

var result = this.scrollTop(item) - item.parentTop;

if (item.centerY)
{
result += (this.windowHeight() - offsetHeight)/2;
}
else if (item.targetTop === undefined)
{
result += this.windowHeight() - item.targetBottom - offsetHeight;
}
else
{
result += item.targetTop;
}

if (document.body != item.menu.parentNode
&& result + offsetHeight >= item.confinedHeightReserve)
{
result = item.confinedHeightReserve - offsetHeight;
}

if (result < 0)
result = 0;

return result;
};

floatingMenu.isConfinementArea = function(item, area)
{
return item.confinementAreaId != undefined
&& area.id == item.confinementAreaId
|| item.confinementAreaClassRegexp != undefined
&& area.className
&& item.confinementAreaClassRegexp.test(area.className);
};

floatingMenu.computeParent = function(item)
{
if (item.ignoreParentDimensions)
{
item.confinedHeightReserve = this.documentHeight();
item.confinedWidthReserver = this.documentWidth();
item.parentLeft = 0;
item.parentTop = 0;
return;
}

var parentNode = item.menu.parentNode;
var parentOffsets = this.offsets(parentNode, item);
item.parentLeft = parentOffsets.left;
item.parentTop = parentOffsets.top;

item.confinedWidthReserve = parentNode.clientWidth;

// We could have absolutely-positioned DIV wrapped
// inside relatively-positioned. Then parent might not
// have any height. Try to find parent that has
// and try to find whats left of its height for us.
var obj = parentNode;
var objOffsets = this.offsets(obj, item);

if (item.confinementArea == undefined)
{
while (obj.clientHeight + objOffsets.top
< item.menu.scrollHeight + parentOffsets.top
|| item.menu.parentNode == obj
&& item.updateParentHeight
&& obj.clientHeight + objOffsets.top
== item.menu.scrollHeight + parentOffsets.top)
{
obj = obj.parentNode;
objOffsets = this.offsets(obj, item);
}
}
else
{
while (obj.parentNode != undefined
&& !this.isConfinementArea(item, obj))
{
obj = obj.parentNode;
objOffsets = this.offsets(obj, item);
}
}

item.confinedHeightReserve = obj.clientHeight
- (parentOffsets.top - objOffsets.top);
};

floatingMenu.offsets = function(obj, item)
{
var result =
{
left: 0,
top: 0
};

if (obj === item.scrollContainer)
return;

while (obj.offsetParent && obj.offsetParent != item.scrollContainer)
{
result.left += obj.offsetLeft;
result.top += obj.offsetTop;
obj = obj.offsetParent;
}

if (window == window.top)
return result;

// we're IFRAMEd
var iframes = window.top.document.body.getElementsByTagName("IFRAME");
for (var i = 0; i < iframes.length; i++)
{
if (iframes[i].contentWindow != window)
continue;

obj = iframes[i];
while (obj.offsetParent)
{
result.left += obj.offsetLeft;
result.top += obj.offsetTop;
obj = obj.offsetParent;
}
}

return result;
};

floatingMenu.doFloatSingle = function(item)
{
this.findSingle(item);

if (item.updateParentHeight)
{
item.menu.parentNode.style.minHeight =
item.menu.scrollHeight + 'px';
}

var stepX, stepY;

this.computeParent(item);

var cornerX = this.calculateCornerX(item);

var stepX = (cornerX - item.nextX) * item.distance;
if (Math.abs(stepX) < .5 && item.snap
|| Math.abs(cornerX - item.nextX) <= 1)
{
stepX = cornerX - item.nextX;
}

var cornerY = this.calculateCornerY(item);

var stepY = (cornerY - item.nextY) * item.distance;
if (Math.abs(stepY) < .5 && item.snap
|| Math.abs(cornerY - item.nextY) <= 1)
{
stepY = cornerY - item.nextY;
}

if (Math.abs(stepX) > 0 ||
Math.abs(stepY) > 0)
{
item.nextX += stepX;
item.nextY += stepY;
this.move(item);
}
};

floatingMenu.fixTargets = function()
{
};

floatingMenu.fixTarget = function(item)
{
};

floatingMenu.doFloat = function()
{
this.fixTargets();
for (var i=0; i < floatingArray.length; i++)
{
this.fixTarget(floatingArray[i]);
this.doFloatSingle(floatingArray[i]);
}
setTimeout('floatingMenu.doFloat()', 20);
};

floatingMenu.insertEvent = function(element, event, handler)
{
// W3C
if (element.addEventListener != undefined)
{
element.addEventListener(event, handler, false);
return;
}

var listener = 'on' + event;

// MS
if (element.attachEvent != undefined)
{
element.attachEvent(listener, handler);
return;
}

// Fallback
var oldHandler = element[listener];
element[listener] = function (e)
{
e = (e) ? e : window.event;
var result = handler(e);
return (oldHandler != undefined)
&& (oldHandler(e) == true)
&& (result == true);
};
};

floatingMenu.init = function()
{
floatingMenu.fixTargets();

for (var i=0; i < floatingArray.length; i++)
{
floatingMenu.initSingleMenu(floatingArray[i]);
}

setTimeout('floatingMenu.doFloat()', 100);
};

// Some browsers init scrollbars only after
// full document load.
floatingMenu.initSingleMenu = function(item)
{
this.findSingle(item);
this.computeParent(item);
this.fixTarget(item);
item.nextX = this.calculateCornerX(item);
item.nextY = this.calculateCornerY(item);
this.move(item);
};

floatingMenu.insertEvent(window, 'load', floatingMenu.init);


// Register ourselves as jQuery plugin if jQuery is present
if (typeof(jQuery) !== 'undefined')
{
(function ($)
{
$.fn.addFloating = function(options)
{
return this.each(function()
{
floatingMenu.add(this, options);
});
};
}) (jQuery);
}

该脚本要求菜单具有#floatdiv id。我制作了我的 div #floatdiv,并在头部添加了以下 javascript 行以使操作开始工作:

<script type="text/javascript">  
floatingMenu.add('floatdiv',
{
targetLeft: 250,

targetTop: 290,

snap: true
});
</script>

#floatdiv CSS 在这里,

#floatdiv{
height:45px;
width:830px;
z-index:2;
}

脚本运行良好。当我向下滚动时,菜单会按指定 float 。但我不想让菜单随着滚动一直 float 。我需要菜单的 float 只有在我输入特定的 div 时才触发,而不是一直滚动。有什么线索吗?

最佳答案

是这个样子吗?

html

<div id="header">HEADER</div>
<div id="content">
<div id="left">LEFT</div>
<div id="right">RIGHT</div>
</div>
<div id="footer">FOOTER</div>

js

$(function() {
var $sidebar = $("#right"),
$window = $(window),
rightOffset = $sidebar.offset(),
rightDelta = $("#footer").offset().top - $("#header").offset().top - $("#header").outerHeight() - $("#right").outerHeight(),
topPadding = 15;

$window.scroll(function() {
$sidebar.stop().animate({
marginTop: Math.max(Math.min($window.scrollTop() - rightOffset.top + topPadding, rightDelta), 0)
});
});

});

工作 demo

希望对你有帮助

关于javascript - 如何使此 float 菜单仅在特定#divs 可见时才起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15725134/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com