我正在尝试将此自定义jQuery滚动条:http://manos.malihu.gr/jquery-custom-content-scroller/安装到我的Facebook Canvas应用程序的模式中,但似乎无法将其应用于正确的div。
我的app / html页面上有一个“邀请”按钮,可以打开一个包含多好友选择器的模式。模态/多好友选择器包含一个div,该div由Javascript创建,然后填充了用户的好友列表。然后,用户可以从此列表中选择要邀请的人。
这是在模态中创建好友列表div的Javascript(mfs
是模态中父div的ID,该父div在创建mfsForm
div后将包含mfsForm
div)。
//Code to login to Facebook’s API goes here…
// Getting the list of friends for the logged in user with the Graph API
FB.api('/me/invitable_friends?limit=48', function(response) {
var container = document.getElementById('mfs');
var mfsForm = document.createElement('form');
mfsForm.id = 'mfsForm';
//This area contains code which goes through each friend and creates an image and name for each one. This populates the mfsForm.
mfsForm
是保存好友列表的div的ID。我正在尝试将滚动条应用于该div。为此,我需要将类“ content mCustomScrollbar”
应用于它。我确定页面上包含正确的脚本,因为我已经通过将相同的类(
“ content mCustomScrollbar”
)应用到div mfs
来测试了滚动条插件,并且该脚本出现在该div的右侧完美,但我想将其应用于mfsForm
。到目前为止,我没有尝试过任何方法,浏览器的默认灰色滚动条是出现在
mfsForm
div上的唯一滚动条。我认为问题可能是由于在Javascript中创建了div mfsForm
。我尝试了以下方法将类应用于
mfsForm
:创建类后,立即将其应用于外部Javascript文件中的
mfsForm
://Code to login to Facebook’s API goes here…
// Getting the list of friends for the logged in user with the Graph API
FB.api('/me/invitable_friends?limit=48', function(response) {
var container = document.getElementById('mfs');
var mfsForm = document.createElement('form');
mfsForm.id = 'mfsForm';
var attempt = document.getElementById("mfsForm");
attempt.className = " content mCustomScrollbar";
//This area contains code which goes through each friend and creates an image and name for each one. This populates the mfsForm.
将类应用于document.ready的html页面中的
mfsForm
:<script>
$(document).ready(function(){
var attempt = document.getElementById("mfsForm");
attempt.className = " content mCustomScrollbar";
});
</script>
单击打开“邀请”模式的按钮,将类应用于html页面中的
mfsForm
://this code is in an external Javascript file:
function applyScroll(){
var attempt = document.getElementById("mfsForm");
attempt.className = " content mCustomScrollbar";
}
//this is the onClick event on the html page:
<a class="invitebutton" href="#openModal" onclick="applyScroll();"></a>
我认为该错误可能是由于将
mfsForm
应用到该类时不存在的,因此我认为仅在文档加载后或单击“邀请”按钮时才应用该错误,因为mfsForm
会在那时创建,但这并没有解决问题。我在控制台中收到以下错误:TypeError:尝试为null
有人可以看到我在做什么吗?我非常感谢您提供有关如何解决此问题的建议。
先感谢您!
更新
当前的HTML代码:
<!doctype html>
<head>
<meta charset="UTF-8">
<title>Facebook App.</title>
<!-- Loading jquery 2.1.3 -->
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<!-- This .js file contains the mfsForm creation code -->
<script type="text/javascript" src="scripts/fb.js"></script>
<!-- This .css file contains the custom scrollbar's default styles -->
<link rel="stylesheet" type="text/css" href='https://cdn.jsdelivr.net/jquery.mcustomscrollbar/3.0.6/jquery.mCustomScrollbar.min.css'>
<!-- This .css file contains the styles for .mfsForm and .content -->
<link rel="stylesheet" type="text/css" href="styles/scrolltestcss.css">
<!-- This is the custom scrollbar's .js file-->
<script src='https://cdn.jsdelivr.net/jquery.mcustomscrollbar/3.0.6/jquery.mCustomScrollbar.concat.min.js'></script>
</head>
<body >
<div>
<a class="invitebutton" href="#openModal"></a>
</div>
<!--Modal-->
<div id="openModal" class="modalDialog">
<div id="mfs">
<div id="wrapper">
</div>
</div>
</div>
</body>
</html>
当前的fb.js文件:
window.fbAsyncInit = function() {
FB.init({
appId: 'myappId',
xfbml: true,
version: 'v2.3'
});
function onLogin(response) {
if (response.status == 'connected') {
FB.api('/me?fields=first_name', function(data) {
var welcomeBlock = document.getElementById('fb-welcome');
welcomeBlock.innerHTML = 'Hello, ' + data.first_name + '!';
});
var jQuery = document.createElement('script');
jQuery.src = 'https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js';
document.head.appendChild(jQuery);
// First get the list of friends for this user with the Graph API
FB.api('/me/invitable_friends?limit=48', function(response) {
var container = document.getElementById('mfs');
var mfsForm = document.createElement('form');
mfsForm.id = 'mfsForm';
mfsForm.className = " content mCustomScrollbar mfsForm";
// Iterate through the array of friends object and create a checkbox for each one.
for (var i = 0; i < response.data.length; i++) {
var friendItem = document.createElement('div');
friendItem.id = 'friend_' + response.data[i].id;
friendItem.style.cssText="width:100px; height:100px; padding:7px; color:#FFF;"
friendItem.style.cssFloat="left";
friendItem.innerHTML = '<input type="checkbox" name="friends" value="' + response.data[i].id + '" />';
var img = document.createElement('img');
img.src = response.data[i].picture.data.url;
img.style.cssText = 'width: 70px;height: 70px;'
friendItem.appendChild(img);
var labelName = document.createElement('label');
labelName.style.cssText = 'font-size: 14px;'
labelName.innerHTML = response.data[i].name;
friendItem.appendChild(labelName);
mfsForm.appendChild(friendItem);
}
container.appendChild(mfsForm);
// Create a button to send the Request(s)
var sendButton = document.createElement('div');
sendButton.id = 'sendButton';
sendButton.onclick = sendRequest;
container.appendChild(sendButton);
$("#filter").keyup(function(){
// Retrieve the input field text and reset the count to zero
var filter = $(this).val()//, count = 0;
// Loop through the comment list
$("#mfsForm div").each(function(){
// If the list item does not contain the text phrase fade it out
if ($(this).text().search(new RegExp(filter, "i")) < 0) {
$(this).fadeOut("fast");
// Show the list item if the phrase matches and increase the count by 1
} else {
$(this).show();
}
});
})
});
}
}
function sendRequest() {
// Get the list of selected friends
var sendUIDs = '';
var mfsForm = document.getElementById('mfsForm');
for (var i = 0; i < mfsForm.friends.length; i++) {
if (mfsForm.friends[i].checked) {
sendUIDs += mfsForm.friends[i].value + ',';
}
}
// Use FB.ui to send the Request(s)
FB.ui({
method: 'apprequests',
to: sendUIDs,
title: 'My Great Invite',
message: 'Add this app!',
}, callback);
}
function callback(response) {
console.log(response);
}
FB.getLoginStatus(function(response) {
if (response.status == 'connected') {
onLogin(response);
} else {
// Otherwise, show Login dialog first.
FB.login(function(response) {
onLogin(response);
}, {
scope: 'user_friends, email'
});
}
});
};
(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) {
return;
}
js = d.createElement(s);
js.id = id;
js.src = "//connect.facebook.net/en_US/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
当前的scrolltestcss.css:
.mfsForm {
padding-left: 90px;
position: absolute;
left: 100px;
top: 250px;
font-family:"Bubblegum Sans";
font-size: 22px;
text-decoration: none;
color: #FFF;
text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000;
margin: auto;
width: 400px;
height: 200px;
overflow: auto;
border: 2px solid red;
}
.content { border: 2px solid green;
}
最佳答案
我updated the fiddle提供此问题的工作副本。它模拟了FB api并修复了参考错误(在加载jquery之前(在onLogin事件之后,在文档准备好之后调用该方法),未定义$
)。
它显示在#mfsForm
CSS选择器中定义的带有红色边框的表单,显示该表单是使用回调创建的。
它具有由JS正确设置的id
和class
属性,只有将边框设置为绿色的.custom
似乎没有作用。
In this fiddle我将#mfsForm
更改为.mfsForm
,现在边框为绿色。
因此,是的,对于您在代码中的要求:
Could this be causing a conflict with " content mCustomScrollbar"? */
#mfsForm {
有一个复杂的rule set governing the priority of css selectors。在这种情况下,
#id
比.class
更具体,因为#id
是(假定是)唯一的,并且只能匹配一个元素,而class
是元素的集合。如果我们change the order of the css rules,则边框变为红色。因此,在定义
.content
和.mCustomScrollbar
的css之前还是之后加载css都将很重要。如果您担心较宽的
.mfsForm
匹配的元素比刚添加的元素更多,可以使用#mfs > .mfsForm
进行引用。这再次改变了as we see here:即使.custom
列在第二位,#mfsForm > .mfsForm
也具有优先权,因为它更具体。使用第三方库时,通常必须检查用于设置样式的特定CSS选择器,并确保使用更特定的CSS选择器,在第三方CSS之后加载它,或者希望该库不使用
!important
并使用它。但是,在此特定情况下,
#mfsForm
的样式覆盖了定义.custom
和/或.mCustomScrollBar
的css中的样式,因为它更具体。更新
Here's a fiddle需要一点时间
不同的方法。
首先,删除所有加载jQuery和mCustomScrollbar的
<script>
标签。由于jQuery是通过注入
<script>
标签动态加载的,因此所需的依赖项jquery.mcustomscrollbar
将不起作用。另外,在加载jQuery之前,我们无法添加加载
jquery.mcustomscrollbar
的脚本标签。因此,我基于this:
function loadScript(url, cb) {
var done = false;
var tmp = document.createElement('script');
tmp.src = url;
tmp.onload = tmp.onreadystatechange = function () {
console.log("onload/readystatechange called");
if (!done || (!this.readyState || this.readyState === "loaded" || this.readyState === "complete")) {
done = true;
tmp.onload = tmp.onreadystatechange = null;
if (cb) cb(tmp);
}
};
document.head.insertBefore(tmp, document.head.firstChild);
}
它将从
url
加载脚本并在完成后调用回调cb
。然后,流程如下:
loadScript('http.....jquery.min.js', function() {
invitableFriends(); // do the FB call and render the form
loadScript('http.....mcustomscrollbar.concat.js', function() {
$('.mcustomScrollBar').mCustomScrollbar();
}
})
问题在于,滚动条插件只会自动将滚动条添加到
onload
处理程序中页面加载时已经存在的元素中。由于将滚动条应用于的元素是动态添加的,因此我们必须显式启用滚动条,就像在回调中加载插件一样。
上面的解决方案可以动态加载所有内容(mcustomscrollbar CSS除外,但是可以更改)。
另类
也可以使用问题中更新代码中的“静态”加载所有内容,但必须显式启用滚动条:
...
container.appendChild(mfsForm);
$(mfsForm).mCustomScrollbar(); // add this line