加载内容异步时,JavaScript无法识别我的功能?

时间:2016-11-06 16:05:25

标签: javascript jquery asynchronous

我希望在文本上有一个“阅读更多”的单击功能。我正在为特定关键字动态加载维基百科文本并具有此功能:

function setText(text, lang, full) {
    setTimeout(function () { $('#loading').fadeOut('fast'); }, 300);
    var mylang = '<?= $_SESSION['lang']; ?>';
    if (mylang != 'en' && lang == 'en')
        var AppendText = '<span class="db f09 grey mt10"><?= __('TEXT_ONLY_ENGLISH'); ?></span>';

    console.log(lang);

    if (full) {
        $('#text').html('<?= __('EMPTY'); ?>');
        setTimeout(function () { $('#text').fadeIn('fast'); }, 500);
    } else if (text) {
        // Full Text
        function fullText() {
            console.log('yes');
            setText(text, lang, 1);
        }

        text = text.length > length ? text.substring(0, length - 3) +
        '... <a class="cp" onclick="fullText()"><?= __('MORE') ?></a>' : text;
        $('#text').html(text).append(AppendText);
        setTimeout(function () { $('#text').fadeIn('fast'); }, 500);
    }
};

正如您在else if部分中所看到的,我将fullText()函数设置为onclick on anchor tag。点击它时,我总是收到消息fullText is not defined。 我只想重新调用相同的setText()函数,并将变量full设置为1,因此将显示全文而不是

  

某种文字...(更多)

这可以不使用ajax吗?我有什么选择?

PS:我也尝试过调用setText()而不是fullText(),但这也不会被识别为已定义的函数。

3 个答案:

答案 0 :(得分:2)

使用onclick属性,您只能引用全局范围内的函数。要解决此问题,您可以动态附加事件处理程序,而不是使用onclick属性。

为了完成这项工作,我建议进行一些更改,以获得以下代码:

function setText(text, lang, full) {
    setTimeout(function () { $('#loading').fadeOut('fast'); }, 300);
    var mylang = '<?= $_SESSION['lang']; ?>';
    // change 1: define an element with jQuery 
    var $appendText = $('<span>');
    if (mylang != 'en' && lang == 'en')
        $appendText.addClass('db f09 grey mt10').text('<?= __('TEXT_ONLY_ENGLISH')?>');

    console.log(lang);

    if (full) {
        // change 2: use text(), not html()
        $('#text').text('<?= __('EMPTY'); ?>');
    } else if (text) {
        // Full Text
        // Change 3: define link as jQuery element:
        var $link = $('<a>');
        if (text.length > length) {
            text = text.substring(0, length - 3);
            $link.addClass('cp').text('<?= __('MORE') ?>');
            // Change 4: attach click handler here:
            $link.click(function fullText() {
                console.log('yes');
                setText(text, lang, 1);
            });
        }
        // Change 5: append these jQuery elements, which can be empty:
        $('#text').text(text).append($link).append($appendText);
    }
    // Change 6: move this out of the if-block, as it is the same for both cases:
    setTimeout(function () { $('#text').fadeIn('fast'); }, 500);
};

请注意,您没有提供变量length的定义,但我认为该函数可以使用它。

答案 1 :(得分:1)

由于function fullText()setText的本地,因此点击事件在全局范围内执行,并且不知道fullText() 不要使用内部html添加A元素,而是通过createElement

执行此操作

类似的东西:

var hr = document.createElement("A");
hr.className="cp";
hr.onclick= function  {
            console.log('yes');
            setText(text, lang, 1);
        }
 $('#text').appendChild(hr)

将创建一个闭包并解决问题。

答案 2 :(得分:1)

编辑:上面的其他答案更好,因为他们利用了jQuery并且更有意义;我的部分解决方案(仅我编辑的编辑)不依赖于jQuery。

尝试这样的事情:

var fullText;
function setText(text, lang, full) {
    setTimeout(function () { $('#loading').fadeOut('fast'); }, 300);
    var mylang = '<?= $_SESSION['lang']; ?>';
    if (mylang != 'en' && lang == 'en')
        var AppendText = '<span class="db f09 grey mt10"><?= __('TEXT_ONLY_ENGLISH'); ?></span>';

    console.log(lang);

    if (full) {
        $('#text').html('<?= __('EMPTY'); ?>');
        setTimeout(function () { $('#text').fadeIn('fast'); }, 500);
    } else if (text) {
        // Full Text
        fullText = function() {
            console.log('yes');
            setText(text, lang, 1);
        }

        text = text.length > length ? text.substring(0, length - 3) +
        '... <a class="cp" onclick="fullText()"><?= __('MORE') ?></a>' : text;
        $('#text').html(text).append(AppendText);
        setTimeout(function () { $('#text').fadeIn('fast'); }, 500);
    }
};

O_Z在他的回答中是正确的,因为function fullText仅在setText()的实例中定义。从function setText内的任何位置调用此函数通常会按照您期望的方式工作,但是您通过编写HTML从全局 fullText()处理程序调用{​​{1}}代码,因此不知道定义相关onclick的{​​{1}}的具体实例。

此解决方案存在一个主要问题,即如果在加载相关文档之前多次调用setText()function fullText将仅引用最新文档,而不是两者。为了解决这个问题,我实际上会创建一个全局数组来存储不同的setText()函数,并写入要在该数组中运行的索引的HTML,然后如果不再需要则从数组中删除存储的函数(以避免内存泄漏)。下面还有另一个例子:

fullText()