我有一个shadowbox脚本。当我加载页面时一切正常,但是当我调用此jquery加载函数然后尝试通过单击图像触发阴影框时,大图像将在新窗口中打开。 这是代码:
<link href="CSS/main.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="shadowbox-3.0.3/shadowbox.js"></script>
<script type="text/javascript">
Shadowbox.init();
</script>
<p id="compas"><a href="images/coverage.jpg" rel="shadowbox" title="Coverage map"></a></p>
知道为什么会这样吗?
答案 0 :(得分:10)
修改强>
所以,我们终于得到了这个的底部。首次评论此问题15个小时后,至少50次迭代后,我们终于确定了问题所在以及如何解决问题。
当我在服务器上创建本地aaa.html
和bbb.html
时,它突然让我感到震惊。就在那时,当$.load()
运行回调函数时,我正在从DOM中删除正被替换的内容的元素节点。因此,一旦#menu-home
内容元素被替换,它们就会从DOM中删除,并且不再应用Shadowbox。
一旦我弄明白了,这只是一个网络搜索的问题,我发现:
Nabble-Shadowbox - Reinit Shadowbox
具体来说,来自mjijackson的回复。他所描述的是如何重新启动&#34; (重新初始化)Shadowbox使用:
Shadowbox.clearCache();
Shadowbox.setup();
所以一旦重新加载#menu-home
内容,需要清除的是Shadowbox缓存(实际上是在页面上关闭它),然后运行Shadowbox.setup()
,这将是再次检测元素。您也无法再次运行Shadowbox.init()
方法。
我注意到您曾尝试在Shadowbox.setup()
之后复制/粘贴$.load()
,至少在代码中按顺序。但是,由于首先需要进行缓存清理,主要因为{/ 1}}和.clearCache()
函数需要在之后运行,因此无法正常工作> .setup()
完成(完成并运行任何回调)。这两个函数需要在$.load()
回调处理程序中运行;否则,您立即运行它,但$.load()
是异步的,将在稍后完成。
我会做一些其他改变,只是让你明白为什么,为什么以及为什么。
注意,我不确定您是否熟悉$.load()
,但以下内容位于<base>
元素的顶部:
HEAD
这只是让我使用您计算机上的资源文件。您不希望在实际网站上使用此功能。如果您复制/粘贴,请确保并删除此行。
<base href="http://62.162.170.125/"/>
在这里,您会注意到我在<div id="menu">
<ul>
<li><a id="menu-home" href="index.html" rel="http://jfcoder.com/test/homecontent.html">Home</a></li>
<li><a id="menu-services" href="services.html" rel="http://jfcoder.com/test/servicescontent.html">Services</a></li>
<li><a id="menu-tour" href="tour.html" rel="http://jfcoder.com/test/tourcontent.html">Tour</a></li>
<li><a id="menulogin" href="login.html">Login</a></li>
</ul>
</div>
属性中有一个相对网址,以及指向我服务器上某些网页的链接。链接到我的服务器的原因是,由于跨站点脚本限制,我无法通过AJAX访问您的HREF
和aaa.html
文件。我的网站链接也应该删除。
现在,我在这里使用bbb.html
属性的原因是我希望允许通过rel
属性的链接继续工作,以防JS没有&#39 ; t功能正常或出现其他一些错误。如果你有单独的文件,一个用于完整的HTML文档,另一个用于片段,这就是你想要做的。如果您可以同时提供完整文档和仅来自链接文件的内容,那么您可能不需要href
属性,但您需要管理请求,以便服务器知道如何回应(完整文件或只是内容部分)。
rel
我在这里所做的就是为初始化/设置请求创建一个中心位置。非常坦率的。注意,我添加了var boxInitialize = function(){
try {
if (!Shadowbox.initialized) {
Shadowbox.init();
Shadowbox.initialized = true;
} else {
Shadowbox.clearCache();
Shadowbox.setup();
}
} catch(e) {
try {
Shadowbox.init();
} catch(e) {};
}
};
属性,因此我可以跟踪Shadowbox.initialized
是否已运行,只能运行一次。但是,如果可能的话,将它们保存在一个位置是个好主意。
我还创建了一个变量函数,可以作为常规函数调用:
Shadowbox.init()
或作为功能参考:
boxInitialize();
您可能会注意到我删除了window.onload = boxInitialize; // Note, no () at the end, which execute the function
并将其替换为$()
。如果你最终得到一个有多个框架和库竞争jQuery()
的环境,这可能会变成一场真正的噩梦,所以最好避免它。这实际上在前几天让我感觉很好。
由于我们在$()
回调中有一个闭包范围,我们可以利用它来保存几个&#34;私有&#34;在脚本执行中不同时间使用ow的变量。
.ready()
请注意除最后一行之外的所有内容的var $ = jQuery,
$content = jQuery("#content"), // This is "caching" the jQuery selected result
view = '',
detectcachedview = '',
$fragment,
s = Object.prototype.toString,
init;
。看看我是如何进口&#34;使,
等于jQuery变量,这意味着你可以在#中实际使用它。
$
当var loadCallback = function(response, status, xhr){
if (init != '' && s.call(init) == '[object Function]') {
boxInitialize();
}
if (xhr.success()
&& view != ''
&& typeof view == 'string'
&& view.length > 1) {
$fragment = $content.clone(true, true);
cacheContent(view, $fragment);
}
};
完成AJAX请求的过程时,它会运行。请注意,请求中返回的内容在运行时已经放在DOM上。另请注意,我们会将实际缓存的内容存储在$.load()
中,这些内容永远不会从页面中删除;只有它下面的内容。
$content.data()
var cacheContent = function(key, $data){
if (typeof key == 'string'
&& key.length > 1
&& $data instanceof jQuery) {
$content.data(key, $data.html());
$content.data(detectcachedview, true);
}
};
是您可能不想要的方法之一;实质上,如果它已经加载到先前的请求上,那么它将被缓存然后直接检索而不是启动另一个cacheContent()
以从服务器获取内容。你可能不想这样做;如果是这样,只需注释掉$.load()
函数中的第二个if
块。
menuLoadContent()
这样做首先清空它的内容/元素的var setContent = function(html){
$content.empty().html(html);
if (init != '' && s.call(init) == '[object Function]') {
boxInitialize();
}
};
元素,然后通过获取$content
添加我们之前保存的指定的基于字符串的标记。这是我们在可能的情况下重新添加的内容;你可以看到一旦点击和加载不同的链接,重新点击以重新显示它是非常快的。此外,如果它与当前加载的请求相同,它也将完全跳过运行代码。
(我们使用$content.html()
之类的,因为它是对包含jQuery元素的变量的引用。我这样做是因为它在一个闭包范围内,这意味着它没有显示在全球范围内,但可用于事件处理程序等。
在代码中查找内联注释。
$content
现在,我选择不同的相关菜单项。您不需要为每个元素单独var menuLoadContent = function(){
// This is where I cancel the request; we're going to show the same thing
// again, so why not just cancel?
if (view == this.id || !this.rel) {
return false;
}
// I use this in setContent() and loadCallback() functions to detect if
// the Shadowbox needs to be cleared and re-setup. This and code below
// resolve the issue you were having with the compass functionality.
init = this.id == 'menu-home' ? boxInitialize : '';
view = this.id;
detectcachedview = "__" + view;
// This is what blocks the superfluous $.load() calls for content that's
// already been cached.
if ($content.data(detectcachedview) === true) {
setContent($content.data(view));
return false;
}
// Now I have this in two different spots; there's also one up in
// loadCallback(). Why? Because I want to cache the content that
// loaded on the initial page view, so if you try to go back to
// it, you'll just pickup what was sent with the full document.
// Also note I'm cloning $content, and then get it's .html()
// in cacheContent().
$fragment = $content.clone(true, true);
cacheContent(view, $fragment);
// See how I use the loadCallback as a function reference, and omit
// the () so it's not called immediately?
$content.load(this.rel, loadCallback);
// These return false's in this function block the link from navigating
// to it's href URL.
return false;
};
声明;相反,我选择了$.click()
,这将获得菜单中#menu a[rel]
元素的每个a
元素。再次,请注意我在这里使用rel="not empty rel attribute"
作为函数引用。
menuLoadContent
然后,在最底部,我运行jQuery("#menu a[rel]").click(menuLoadContent);
来设置Shadowbox。
如果您有任何问题,请与我们联系。
我想我可能会深究这一点。我认为这个缺陷就是你点击一个菜单项时处理新内容的boxInitialize();
的方式,再加上我看到与$.load()
有关的未被捕获的异常:
未捕获的异常:未知的玩家iframe
此Nabble-Shadowbox forum thread处理此错误。我实际上不再那样了,但是我认为我点击了iframe
菜单项。
现在,您为菜单项加载内容所做的工作实际上没有任何意义。您正在请求整个HTML文档,然后只选择一个tour
的元素。我可以看到这样做的唯一好处是页面永远不会重新加载,但你需要采取另一种方法来获取和显示不涉及通过AJAX下载整个页面然后尝试获取jQuery的数据只解析你想要的部分。
我认为以这种方式处理内容是问题的根本原因,因此class="content"
切换菜单视图会以意想不到的方式破坏您的网页。
问题:为什么不直接链接到实际页面并跳过所有$.load()
幻想?速度方面,如果有的话,它不会产生那么大的影响。使用这样的AJAX是没有意义的,只要你可以将它们链接到相同的内容而没有问题。
有两种方法可以防止往返页面重新加载:
如果您在网址中有$.load()
标记,而不是整个HTML文档,则将您的AJAX调用设置为仅请求标记的.content
部分。这就是它传统上的完成方式,如果您有脚本环境,通常会相对简单。
?contentonly=true
然后您的服务器仅响应请求的内容视图。
在同一HTML文档中提供所有内容视图,然后根据需要显示:
$(".content").load('index.html?contentonly=true');
看起来您没有提供完整的批次内容,因此初始页面加载可能不会对此特定方法产生太大影响。您可能需要研究如何预加载图像,但这是一种非常着名的技术,其中包含许多高质量的脚本和教程。
这些技术中的任何一种都可以使用var $content = $('.content');
$content.find('.content-view').hide();
$content.find('#services-content').show();
(hashbang)技术来加载内容,但我相信搜索引擎存在一些问题。但是,这里有一个链接到我前段时间放在一起的简单技术:
http://jfcoder.com/test/hash.html
此外,这只是一个提示,但不要参考您的内容&#34;带有#!
的元素,即class
。标记中应该只有一个内容显示元素,对吧?那不超过一个?使用.content
;这是id="content"
属性的用途,用于引用单个元素。 ID
es旨在按照他们共享的某些特征对元素进行分组,因此,当我class
内联内容视图(请参阅#2)时,我会查找所有.hide()
元素,都是相似的(它们包含内容视图标记)。但class="content-view"
变量应引用$content
。这描述了元素是什么。
答案 1 :(得分:1)
这对我们有用,我们创建了一个使用垂直标签的网站,并使用jQuery.load在我们的shadowbox图像页面中调用
只需将所有锚标记设为class =“sbox”,然后将此脚本粘贴到标题中即可。
<script>
Shadowbox.init({
skipSetup:true,
});
$(document).ready(function() {
Shadowbox.setup($('.sbox'));//set up links with class of sbox
$('a.sbox').live('click',function(e){
Shadowbox.open(this);
//Stops loading link
e.preventDefault();
});
});
</script>
注意:我们必须将.sbox类放在我们所有的rel =“shadowbox”锚点上,以及调用.load
的选项卡的锚点上。感谢这个家伙 - &gt; http://www.webmuse.co.uk/blog/shadowbox-ajax-and-other-generated-content-with-jquery-and-javascript/
答案 2 :(得分:0)
嗯,根据Shem的回答,这是我的解决方案。 每次单击特定类,设置和打开包含来自同一类的元素的影子框:
jQuery('.sb-gallery a').live('click',function(e){
Shadowbox.setup(jQuery('.sb-gallery a'));
Shadowbox.open(this);
//Stops loading link
e.preventDefault();
});
感谢所有