2016-11-06 118 views
0

我想在文本上有一个“多读”功能。我动态加载特定关键字维基百科文本和具有这样的功能:加载内容异步时,JavaScript无法识别我的功能?

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锚标记。当我点击它时,我总是收到消息fullText is not defined。 我只是想重新调用相同setText()函数变量full设置为1,使全文将显示

Sometext的,而不是...(更多)

这是可能不使用ajax?我有什么选择? PS:我也已经尝试过拨打setText()本身,而不是fullText(),但那也不会被识别为定义的功能。

+1

与您的问题没有关系,但仅供参考,您不需要那些'setTimeout'调用。你可以使用'.delay()'来代替。 '$('#text')。delay(500).fadeIn('fast');' – 2016-11-06 16:07:26

+1

好的,很高兴知道,谢谢。 @squint – AlexioVay

+3

'fullText'函数的作用域被定义为函数的地方,所以'onclick'属性将无法看到它,因为它将在全局范围内查找它。 – 2016-11-06 16:09:27

回答

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的定义,但我相信它是提供给功能。

+0

你是一个天才,谢谢。 – AlexioVay

1

因为function fullText()是本地setText click事件执行对全球范围内,并且不被知道的fullText() 不要用内部HTML添加一个元素,但这样做createElement

类似:

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

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

+0

如果我把它放在'setText()'之外,它也不会被识别。 – AlexioVay

+0

@Vaia OK也给了解决方案 –

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代码从全局onclick调用fullText()处理程序,因此不知道setText()的特定实例的定义相关function fullText

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

var fullTextFunctions = []; 
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 
     fullTextFunctions.push(function fullText() { 
      console.log('yes'); 
      setText(text, lang, 1); 
     }) 

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

function releaseFullTextFunction(index) { 
    fullTextFunctions[index] = null; 
} 
+0

谢谢你这个详细的答案,我真的很感激它,并且学到了很多!很高兴知道JS如何在后台工作。所以据我了解,你的意思是如果'文字'会改变,我应该更喜欢用数组创建这个解决方案? – AlexioVay

+0

更多的是,如果在调用fullText之前多次调用函数'setText',变量/函数'fullText'只引用最近一次'setText'被调用。所以如果你想让'setText'的不同实例引用'fullText'的不同实例,你必须将实例存储在一个具有唯一标识符的全局数组/对象中,假设你坚持从HTML'onclick'调用'fullText' '处理程序。 – Sabumnim