检测:javascript的第一个字母

时间:2013-07-31 12:15:34

标签: javascript css

我需要知道元素是否使用:first-letter样式设置样式,它应该是一般解决方案,因此我不会依赖于类名或特殊样式属性。有什么办法吗?例如:

<p class="initial">First</p>
<p>Second</p>

.initial:first-letter {
float: left;
font-size: 1.5em;
font-weight: bold;
}

$('p').click(function(){
    // how to determine if :first-letter is applied to current paragraph?

});

3 个答案:

答案 0 :(得分:3)

如果您的CSS是自托管的,您可以:

  1. 获取所有CSS块的列表
  2. 过滤出块选择器中不包含:first-letter的CSS块
  3. 迭代剩余的CSS块列表,并以目标元素作为接收者和当前CSS块的选择器作为参数运行matchesSelector()
    1. 如果matchesSelector()返回true,则当前CSS块的规则会影响目标元素的第一个字母。
    2. 否则转到列表中的下一个CSS块
  4. 如果CSS不是自托管的并且CDN不发送CORS标头,那么您无法读取CSS文件源 由于隐私问题,这是无法做到的。

    我也没有从算法中找出规则级联。另一个障碍是弄清楚伪选择器会以错误的方式影响matchesSelector

    喜欢考虑:

    p.webkitMatchesSelector("p:first-letter") //false
    

    因此,在尝试匹配之前,必须从字符串中删除:first-letter之类的伪,因为它们无关(但:nth-child之类的伪不是因为它们真正影响匹配)。

    演示http://jsfiddle.net/PBuzb/5/(请记住我提到的问题在这里处理得不好)(最初由Crush编写的代码基础)


    为什么不允许在跨源情况下读取CSS源?

    你只能显示图像,运行css / js等来自其他域名的原因但绝对不能以任何方式访问他们的数据是隐私。

    这种情况最容易制作图像。假设我已经登录到facebook,并且facebook使用网址作为私人照片 http://facebook.com/myprofile.png。现在我去evil.com,evil.com可以加载图像因为我登录到facebook, Facebook会给他们那个形象。通常情况下,无论如何他们都无法访问图像或窃取它,但如果我们启用了 跨域数据访问,他们现在可以访问我的私人照片并将其展开。

    在CSS中可能会发生同样的情况,可能存在由facebook服务器生成的用户特定的CSS,其中包含我的私有用户ID 朋友。他们不再那么私密,如果我可以去的任何网站都可以链接到那个CSS并开始阅读它。

    是的,主要问题是如果浏览器在请求时没有发送cookie,浏览器如何发送带有跨源请求的cookie facebook images / css来自evil.com,然后facebook无法回复用户特定的CSS或我的私人照片,因为饼干 有必要认出我。

    现在假设浏览器没有发送cookie。 Evil.com仍然可以通过这种方式访问​​任何Intranet数据,因为我的浏览器可以访问Intranet。能够在evil.com网站上显示http://intranet/Myboss.jpg作为图像不是问题,但是Evil.com能够读取图像数据并因此能够复制和传播它是一个问题。

答案 1 :(得分:2)

您可以迭代cssRules,构建所有::first-letter规则的数组,然后检查该元素是否具有这些规则之一。

Working DEMO(仅在Chrome中测试)

(function() {
    var firstLetterRules = [];

    var loadRules = function() {
        var stylesheets = document.styleSheets;

        for (var i = 0; i < stylesheets.length; i++) {
            var stylesheet = stylesheets[i];
            var rules = stylesheet.cssRules;

            for (var k = 0; k < rules.length; k++) {
                var rule = rules[k];

                if (rule.selectorText.indexOf("::first-letter") !== -1) {
                    //It is a ::first-letter selector. Add the rule to a list of ::first-letter rules.
                    firstLetterRules.push(rule.selectorText.toUpperCase());
                }
            }
        }
    };

    window.hasFirstLetterStyle = function(element) {
        var fullSelector = element.nodeName;

        if (element.className != '')
            fullSelector += '.' + element.className;

        fullSelector = fullSelector.toUpperCase() + "::FIRST-LETTER";

        for (var i = 0; i < firstLetterRules.length; i++) {
            if (fullSelector == firstLetterRules[i])
                return true;
        }

        return false;
    };

    loadRules();
})();

var element = document.getElementById("init");

if (hasFirstLetterStyle(element)) {
    console.log("Element has a first-letter style rule.");
}

答案 2 :(得分:1)

你不能。

您的JS代码无法访问伪选择器及其样式。

你可以做的最接近的事情是检查元素是否具有触发first-letter样式的相关类,并在JS代码中假设如果类在那里,那么first-letter风格必须已经应用。

除了手动解析整个CSS文件之外,没有其他办法。

这也适用于其他伪选择器和伪元素(你会在这里找到一些类似的问题,询问有关:before:after的类似问题,并提供相似的答案)