将JavaScript的onclick事件更改为jQuery的click事件,并仍然传递参数。

3

我觉得我可能错过了什么或者还没有掌握jQuery的基本知识。我已经搜索了几个小时,但是还没有找到我的问题的答案。

我正在升级一个旧网站,使用jQuery,并且许多链接调用JavaScript的onClick函数并传递多个参数,如下面的示例:

<a href="#" onclick="displayData('Book Title', 'ISBN', 'dateOfPublishing', 'Price');">View Details</a>

问题在于我已经使用各种jQuery代码更新了旧的displayData函数,而displayData函数位于

标签内。

$(document).ready(function() { 
});

代码中出现了问题,似乎阻止了使用onClick调用displayData函数,因为它提示对象期望。我已将displayData函数从$(document).ready()移出,但这样做会阻止引用$(document).ready()代码内的其他函数。

以下是一个简化的示例:

<script>
  $(document).ready(function() {
    function displayData(title, isbn, dt, price) {
      // there's a call to jQuery AJAX here
        $.ajax({
            type: "POST",
            contentType: "application/json; charset=utf-8",
            url: "WebServices/BookService.asmx/GetBookReviews",
            data: "{isbn: '" + isbn + "'}",
            dataType: "json",
            success: function(msg) {
                DisplayReviews(msg.d);
            }
        });
      return false;
    }

    function DisplayReviews(data) {
       // data normally formatted here and passed to formattedData variable
       var formattedData = FormatData(data);
       $('#reviewScreen').html(formattedData);
    }

    function FormatData(data) {
      // function reformats data... code removed for space..
      return data;
    }


  });
</script>


<table>
  <tr><td><a href="#" class="reviewLink" onclick="displayData('Book Title', '1234141HABJA1', '2010-01-12', '$15.99');">View Reviews</a></td><td>Book Title</td></tr>
  <tr><td><a href="#" class="reviewLink" onclick="displayData('Book TItle 2', '516AHGN1515', '1999-05-08', '$25.00');">View Reviews</a></td><td>Book Title 2</td></tr>
</table>

我希望你能够帮助我将链接中的 onclick="displayData();" 移除,并改用 jQuery 的 click 函数,类似于:
$('a.reviewLink').click(function() {
  displayData(parameters go here....);
});

我不知道如何从链接中传递参数给函数,因为它们不再在HTML的onclick属性中。

如果我继续在链接中使用onclick属性,并将displayData(params)移出$(document).ready()代码块,它可以正常工作,但是一旦我尝试引用$(document).ready()代码块内的其他函数,例如DisplayReviews(param),就会出现可怕的“对象期望”错误。

我不知道这是否有意义...抱歉如果有些混乱,我不是世界上最好的程序员,也不一定知道所有术语,所以尽我所能地解释。希望你能帮忙。

非常感谢


你能修改HTML吗?还是需要从现有的onclick属性中提取参数? - Anurag
我可以修改HTML,只是不确定是否要坚持现有的onclick或尝试更好地利用jQuery并以其他方式提取参数。HTML是动态生成的,因此必要的参数在此时附加,这就是为什么我曾经使用onclick属性的原因。谢谢! - Cydaps
您可以动态创建所需的JavaScript代码(即动态附加单击处理程序)。 - Felix Kling
@Felix:我会看看动态附加单击处理程序的做法,但确实喜欢BGerrissen所提到的HTML5的想法。 - Cydaps
3个回答

8

初始化代码应该放在 .ready() 中,而不是你的库函数中,这些函数可以在一个单独的 .js 文件中定义。

<script src="yourFunctions.js"></script>
<script>
    $(document).ready(function(){

         $('a.reviewLink').click(function() {
             displayData(parameters go here....); // in yourFunctions.js
         });

    });
</script>

一种不使用内联JavaScript传递内联参数的替代方法是使用HTML5标签上的"data-"属性。您可以在xhtml、html等中使用它,并且它会正常工作。

html:

<div data-name="Jack" data-lastname="black">My name is</div>

jquery:

 $('div').click(function(){
      alert($(this).attr('data-name') + ' ' + $(this).attr('data-lastname'));
 });

注意:您必须使用jQuery的.attr()或本地的.getAttribute()方法来检索"data-"值。
我自己经常使用"data-"。

嗨,BGerrissen,谢谢。我唯一不清楚的事情是如何获取参数。HTML 最初是动态生成的,这就是为什么我使用了 onclick="displayData(params);" 属性,因为我在运行时将参数值定义到每个链接中。我可以看到上面的示例是如何工作的,但我就是看不出当我单击链接时要传递给 displayData 的参数来自哪里。抱歉我有点迟钝! :-) - Cydaps
太酷了!我猜它需要一个不同的文档类型...我会在网上搜索哪个适用于HTML5,这听起来完美!! :-) - Cydaps
不需要使用不同的文档类型,只有在HTML验证很重要的情况下才需要,即使在这种情况下,你的HTML很可能是无效但实际上有效的... - BGerrissen
将代码进行移动非常成功,我已经采用了HTML5数据属性。DocType似乎适用于我测试过的所有浏览器。它甚至可以与我之前使用的旧onclick =“”属性一起使用!谢谢! - Cydaps
@BGerrissen... 在您的评论中,您说必须使用.attr()或.getAttribute()。我认为您也可以使用jQuery的.data()。请参阅jQuery文档:http://api.jquery.com/data/ - David S
现在你可以,但是在2010年你不能。 - BGerrissen

1
如Skilldrick所指出的那样,displayData不需要在文档准备好后的包装器内定义(也许不应该这样做)。
您想使用jQuery点击事件分配而不是onClick是正确的 - 它使您的代码更易于阅读,并且符合无侵入式JavaScript原则的要求。
至于您想要传递的那些参数,有几种方法可以完成任务。如果您不关心XHTML兼容性,可以简单地在链接上放置一些自定义属性,然后从脚本中访问它们。例如:
<a href="#" booktitle="Book Title" isbn="ISBN" pubdate="Publish Date" price="Price">View Details</a>

然后在您的点击事件中:

$('a.reviewLink').click(function() {
  var booktitle = $(this).attr('booktitle');
  var isbn = $(this).attr('isbn');
  var pubdate = $(this).attr('pubdate');
  var price = $(this).attr('price');
  displayData(booktitle, isbn, pubdate, price);
});

我相信这里会有人谴责这种方法为最黑暗的邪恶,但在过去它对我来说效果很好。或者,你可以在每个链接后面跟随一组隐藏的数据,像这样:

<a href="#">View Details</a>
<ul class="book-data">
   <li class="book-title">Book Title</li>
   <li class="book-isbn">ISBN</li>
   <li class="book-pubdate">Publish Date</li>
   <li class="book-price">Price</li>
</ul>

创建一个CSS规则来隐藏数据列表:.book-data { display: none; },然后在您的点击事件中:
$('a.reviewLink').click(function() {
  var $bookData = $(this).next('.book-data');
  var booktitle = $bookData.children('.book-title').text();
  var isbn = $bookData.children('.book-isbn').text();
  var pubdate = $bookData.children('.book-pubdate').text();
  var price = $bookData.children('.book-price').text();
  displayData(booktitle, isbn, pubdate, price);
});

有很多方法可以完成你的任务,但这两种方法最容易想到。


谢谢,这些想法也很有用!我猜HTML5的"data"属性标签已经取代了它,但作为替代方案真的很有用。 :-) - Cydaps
是的,那些数据属性标签绝对干净地解决了这个问题。使用它们的唯一问题是,如果您需要支持不支持HTML5的旧浏览器,则可能会出现问题。不过,如果您正在支持旧浏览器,则XHTML兼容性可能是一个问题,因此普通自定义属性仍无法使用... - Ender
@Ender:是的,它们可以在IE6中使用,参见Do HTML5 custom data attributes “work” in IE 6? - Marcel Korpel
@Marcel - 抱歉,我表达不清楚。我并不是说它会出错,只是自定义属性不符合XHTML标准,无法通过W3C验证器的标准。当然,你可以定义自己的文档类型,但这本身就是一个麻烦。 - Ender
1
答案非常简单,只需要加上'<!DOCTYPE html>';您的头疼问题将立即消失,而且比买扑热息痛药更便宜。 - Marcel Korpel
我选择使用了 <!DOCTYPE html>,它在 IE6+、Chrome 和 Firefox 3 上都能正常工作,看起来是一个很好的选择。 :-) - Cydaps

0
我写了这个,所以即使问题得到了解答,其他人也可能会发现它有帮助。 http://jsbin.com/axidu3 HTML
<table border="0" cellspacing="5" cellpadding="5">
    <tr>
        <td>
            <a href="#" class="reviewLink">View Reviews</a>
            <div class="displayData">
                <span class="title">Book Title 2</span>
                <span class="isbn">516AHGN1515</span>
                <span class="pubdata">1999-05-08</span>
                <span class="price">$25.00</span>
            </div>
            </td>
        <td>Book Title 2</td>
    </tr>
</table>

JavaScript

<script type="text/javascript" charset="utf-8">
    jQuery(".reviewLink").click(function() {
        var title = jQuery(".title", this.parent).text();
        var isbn  = jQuery(".isbn", this.parent).text();
        var pubdata = jQuery(".pubdata", this.parent).text();
        var price = jQuery(".price", this.parent).text();

        displayData(title, isbn, pubdata, price);
    });

    function displayData(title, isbn, pubdata, price) {
        alert(title +" "+ isbn +" "+ pubdata +" "+ price);
    }
</script>

CSS

<style type="text/css" media="screen">
    .displayData {
        display: none;
    }
</style>

这绝对是一个不错的解决方案,如果不使用HTML5数据属性的话。感谢Sandro提供如此干净的示例。 - Cydaps

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接