我正在尝试将此自定义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正确设置的idclass属性,只有将边框设置为绿色的.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

09-11 06:56