Igo*_*gor 8 javascript jquery shadowbox
我有一个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>
Run Code Online (Sandbox Code Playgroud)
知道为什么会这样吗?
Jar*_*ish 10
编辑
所以,我们终于明白了这一点.首次评论此问题15个小时后,至少50次迭代后,我们终于确定了问题是什么以及如何解决问题.
当我在我的服务器上创建本地aaa.html和bbb.html服务器时,它实际上突然袭击了我.就在那时我发现在$.load()运行回调函数时,正在被替换的内容的元素节点从DOM中被完全删除.因此,一旦#menu-home替换了内容元素,就会从DOM中删除它们,并且不再将Shadowbox应用于它们.
一旦我弄明白了,这只是一个网络搜索的问题,我发现:
Nabble-Shadowbox - 重新启动Shadowbox
具体来说,mjijackson的回应.他描述的是如何使用以下方式"重启"(重新初始化)Shadowbox:
Shadowbox.clearCache();
Shadowbox.setup();
Run Code Online (Sandbox Code Playgroud)
因此,一旦#menu-home重新加载内容,需要清除的是Shadowbox缓存(实质上是在页面上关闭它),然后Shadowbox.setup()运行,这将再次检测元素.您也不会Shadowbox.init()再次运行该方法.
我注意到您曾试图复制/粘贴Shadowbox.setup()后的$.load()代码,至少顺序.但是,这是行不通的,因为需要发生第一次,主要是因为在清除缓存.clearCache()和.setup()功能需要运行后,将$.load()完成(完成并运行任何回调).这两个函数需要在$.load()回调处理程序中运行; 否则,你立即运行它,但它$.load()是异步的,将在稍后完成.
我将继续进行其他一些改变,让你明白为什么,为什么以及为什么.
注意,我不确定你是否熟悉<base>,但以下是HEAD元素的顶部:
<base href="http://62.162.170.125/"/>
Run Code Online (Sandbox Code Playgroud)
这只是让我使用您计算机上的资源文件.您不希望在实际网站上使用此功能.如果您复制/粘贴,请确保并删除此行.
<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>
Run Code Online (Sandbox Code Playgroud)
在这里,您会注意到我在HREF属性中有一个相对URL ,以及指向我服务器上某些页面的链接.究其原因,链接到我的服务器是,我无法访问您aaa.html,并bbb.html通过AJAX的文件,由于跨站点脚本的限制.我的网站链接也应该删除.
现在,我在rel这里使用属性的原因是我希望通过href属性允许链接继续工作,以防JS无法正常运行或出现其他一些错误.如果你有单独的文件,一个用于完整的HTML文档,另一个用于片段,这就是你想要做的.如果您可以同时提供完整文档和仅来自链接文件的内容,那么您可能不需要该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) {};
}
};
Run Code Online (Sandbox Code Playgroud)
我在这里所做的就是为初始化/设置请求创建一个中心位置.非常坦率的.注意,我添加了Shadowbox.initialized属性,所以我可以跟踪是否Shadowbox.init()已运行,只能运行一次.但是,如果可能的话,将它们保存在一个位置是个好主意.
我还创建了一个变量函数,可以作为常规函数调用:
boxInitialize();
Run Code Online (Sandbox Code Playgroud)
或作为功能参考:
window.onload = boxInitialize; // Note, no () at the end, which execute the function
Run Code Online (Sandbox Code Playgroud)
您可能会注意到我删除了$()并替换了它们jQuery().如果你最终得到一个有多个框架和库竞争的环境,这可能会变成一场真正的噩梦$(),所以最好避免它.这实际上只是让我在前几天真正的好.
由于我们在.ready()回调中有一个闭包范围,我们可以利用它来保存几个"私有"变量,以便在脚本执行的不同时间使用ow.
var $ = jQuery,
$content = jQuery("#content"), // This is "caching" the jQuery selected result
view = '',
detectcachedview = '',
$fragment,
s = Object.prototype.toString,
init;
Run Code Online (Sandbox Code Playgroud)
注意,除了最后一行之外的所有末尾.$通过使其等于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);
}
};
Run Code Online (Sandbox Code Playgroud)
这在$.load()完成AJAX请求的过程时运行.请注意,请求中返回的内容在运行时已经放在DOM上.还要注意,我们将实际缓存的内容存储在$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);
}
};
Run Code Online (Sandbox Code Playgroud)
cacheContent()是一种你可能不想要的方法; 实际上,如果它已经加载到先前的请求上,那么它将被缓存然后直接检索而不是启动另一个$.load()来从服务器获取内容.你可能不想这样做; 如果是这样,只需注释掉函数中的第二个if块menuLoadContent().
var setContent = function(html){
$content.empty().html(html);
if (init != '' && s.call(init) == '[object Function]') {
boxInitialize();
}
};
Run Code Online (Sandbox Code Playgroud)
这样做首先清空$content它的内容/元素的元素,然后添加我们之前保存的指定的基于字符串的标记$content.html().这是我们在可能的情况下重新添加的内容; 你可以看到一旦点击和加载不同的链接,重新点击以重新显示它是非常快的.此外,如果它与当前加载的请求相同,它也将完全跳过运行代码.
(我们之所以使用,$content是因为它是对包含jQuery元素的变量的引用.我这样做是因为它在一个闭包范围内,这意味着它不会出现在全局范围内,但可用于事件之类的事情处理程序.
在代码中查找内联注释.
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;
};
Run Code Online (Sandbox Code Playgroud)
现在,我以不同的方式选择相关的菜单项.您不需要$.click()为每个元素单独声明; 相反,我选择了#menu a[rel],它将获得a菜单中具有的每个元素rel="not empty rel attribute".再次,请注意我menuLoadContent在这里如何用作函数引用.
jQuery("#menu a[rel]").click(menuLoadContent);
Run Code Online (Sandbox Code Playgroud)
然后,在最底部,我运行boxInitialize();设置Shadowbox.
如果您有任何疑问,请告诉我.
我想我可能会深究这一点.我认为缺点是你$.load()在点击一个菜单项时处理新内容的方式,再加上我看到与一个未被捕获的异常iframe:
未捕获的异常:未知的玩家iframe
这个Nabble-Shadowbox论坛帖子处理这个错误.我实际上不再那样了,但我认为它是我点击了tour菜单项.
现在,你正在做什么来加载菜单项的内容真的没有任何意义.您正在请求整个HTML文档,然后只选择一个带有的元素class="content".我可以看到这样做的唯一好处是页面永远不会重新加载,但你需要采取另一种方法来获取和显示不涉及通过AJAX下载整个页面然后尝试解析jQuery的数据只是你想要的部分.
我认为以这种方式处理内容是导致问题的根本原因,因此$.load()菜单视图的切换会以意想不到的方式破坏您的页面.
问题:为什么不直接链接到实际页面并跳过所有的$.load()幻想?速度方面,如果有的话,它不会产生那么大的影响.使用这样的AJAX是没有意义的,只要你可以将它们链接到相同的内容而没有问题.
有两种方法可以防止往返页面重新加载:
.content如果您?contentonly=true在URL中有标记而不是整个HTML文档,则将AJAX调用设置为仅请求标记的一部分.这就是它传统上的完成方式,如果您有脚本环境,通常会相对简单.
$(".content").load('index.html?contentonly=true');
Run Code Online (Sandbox Code Playgroud)
然后,您的服务器仅响应请求的内容视图.
在同一HTML文档中提供所有内容视图,然后根据需要显示:
var $content = $('.content');
$content.find('.content-view').hide();
$content.find('#services-content').show();
Run Code Online (Sandbox Code Playgroud)
看起来你没有提供很多内容,因此初始页面加载可能不会对这种特定方法产生太大影响.您可能需要研究如何预加载图像,但这是一种众所周知的技术,其中包含许多高质量的脚本和教程.
这些技术中的任何一种都可以使用#!(hashbang)技术来加载内容,但我相信搜索引擎存在一些问题.但是,这里有一个链接到我前面放在一起的简单技术:
http://jfcoder.com/test/hash.html
此外,这只是一个提示,但不要引用你的"内容"元素class,即.content.标记中应该只有一个内容显示元素,对吧?不只有一个?用一个id="content"; 这就是ID引用单个元素的属性.classes意味着按照它们共享的某些特征对元素进行分组,所以当我.hide()在内联内容视图(参见#2)时,我会查找class="content-view"所有相似的元素(它们包含内容视图标记).但$content变量应该参考$('#content');.这描述了元素是什么.
| 归档时间: |
|
| 查看次数: |
8191 次 |
| 最近记录: |